grambot 1.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +126 -0
  3. package/dist/action/action.d.ts +17 -0
  4. package/dist/action/action.d.ts.map +1 -0
  5. package/dist/action/action.js +59 -0
  6. package/dist/action/action.js.map +1 -0
  7. package/dist/conversation/conversation.d.ts +15 -0
  8. package/dist/conversation/conversation.d.ts.map +1 -0
  9. package/dist/conversation/conversation.js +346 -0
  10. package/dist/conversation/conversation.js.map +1 -0
  11. package/dist/engine/engine.d.ts +24 -0
  12. package/dist/engine/engine.d.ts.map +1 -0
  13. package/dist/engine/engine.js +847 -0
  14. package/dist/engine/engine.js.map +1 -0
  15. package/dist/grambot.d.ts +142 -0
  16. package/dist/grambot.d.ts.map +1 -0
  17. package/dist/grambot.js +204 -0
  18. package/dist/grambot.js.map +1 -0
  19. package/dist/index.d.ts +31 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +28 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/menu/button.d.ts +99 -0
  24. package/dist/menu/button.d.ts.map +1 -0
  25. package/dist/menu/button.js +157 -0
  26. package/dist/menu/button.js.map +1 -0
  27. package/dist/menu/layout.d.ts +86 -0
  28. package/dist/menu/layout.d.ts.map +1 -0
  29. package/dist/menu/layout.js +90 -0
  30. package/dist/menu/layout.js.map +1 -0
  31. package/dist/menu/list.d.ts +43 -0
  32. package/dist/menu/list.d.ts.map +1 -0
  33. package/dist/menu/list.js +60 -0
  34. package/dist/menu/list.js.map +1 -0
  35. package/dist/menu/menu.d.ts +29 -0
  36. package/dist/menu/menu.d.ts.map +1 -0
  37. package/dist/menu/menu.js +73 -0
  38. package/dist/menu/menu.js.map +1 -0
  39. package/dist/telebot.d.ts +142 -0
  40. package/dist/telebot.d.ts.map +1 -0
  41. package/dist/telebot.js +204 -0
  42. package/dist/telebot.js.map +1 -0
  43. package/dist/types.d.ts +322 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +2 -0
  46. package/dist/types.js.map +1 -0
  47. package/dist/ui/ui.d.ts +12 -0
  48. package/dist/ui/ui.d.ts.map +1 -0
  49. package/dist/ui/ui.js +39 -0
  50. package/dist/ui/ui.js.map +1 -0
  51. package/package.json +55 -0
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Fluent builder for a single inline button.
3
+ *
4
+ * Usage (from LayoutBuilder):
5
+ * ```ts
6
+ * layout.button("Label")
7
+ * .id("unique")
8
+ * .row()
9
+ * .guard(ctx => ctx.user.isAdmin)
10
+ * .action(someAction)
11
+ * ```
12
+ */
13
+ export class ButtonBuilder {
14
+ /** @internal */
15
+ _config;
16
+ /**
17
+ * @internal Use `layout.button()` instead.
18
+ */
19
+ constructor(label) {
20
+ this._config = {
21
+ label,
22
+ forceRow: false,
23
+ isDefault: false,
24
+ };
25
+ }
26
+ /**
27
+ * Set a stable callback-data identifier for this button.
28
+ * If not set, one will be generated automatically.
29
+ */
30
+ id(value) {
31
+ this._config.buttonId = value;
32
+ return this;
33
+ }
34
+ /**
35
+ * Set a URL for this button. Turns it into a URL button.
36
+ */
37
+ url(value) {
38
+ this._config.url = value;
39
+ return this;
40
+ }
41
+ /**
42
+ * Force this button onto a new row in the keyboard.
43
+ */
44
+ row() {
45
+ this._config.forceRow = true;
46
+ return this;
47
+ }
48
+ /**
49
+ * Only show this button if the guard returns true.
50
+ * @param fn - A synchronous or asynchronous guard function.
51
+ */
52
+ guard(fn) {
53
+ this._config.guard = fn;
54
+ return this;
55
+ }
56
+ /**
57
+ * Attach an action handler.
58
+ *
59
+ * Accepts:
60
+ * - An `ActionRef` (created via `Grambot.action`)
61
+ * - An inline async/sync function
62
+ * - A simple `() => void` for client-side only changes? (No, usually needs context)
63
+ *
64
+ * @param handler - The handler to execute on click.
65
+ */
66
+ action(handler) {
67
+ if (typeof handler === "function") {
68
+ if (handler.constructor.name === "AsyncFunction") {
69
+ this._config.inlineHandler = handler;
70
+ this._config.action = undefined;
71
+ }
72
+ else {
73
+ this._config.action = handler;
74
+ this._config.inlineHandler = undefined;
75
+ }
76
+ }
77
+ else {
78
+ this._config.action = handler;
79
+ this._config.inlineHandler = undefined;
80
+ }
81
+ return this;
82
+ }
83
+ /**
84
+ * Open a sub-menu when this button is pressed.
85
+ * @param ref - The menu reference to open.
86
+ */
87
+ menu(ref) {
88
+ this._config.submenu = ref;
89
+ return this;
90
+ }
91
+ /**
92
+ * Attach a typed payload to this button.
93
+ * The payload is serialized into the callback data and passed to the action.
94
+ */
95
+ payload(data) {
96
+ this._config.payload = data;
97
+ return this;
98
+ }
99
+ /**
100
+ * Mark this button as the default inside its menu.
101
+ * Default buttons are triggered if the user sends text that doesn't match any other button.
102
+ */
103
+ default() {
104
+ this._config.isDefault = true;
105
+ return this;
106
+ }
107
+ /**
108
+ * Set a color style for this button.
109
+ * Available styles: "danger" (red), "success" (green), "primary" (blue).
110
+ * Requires Telegram Bot API 9.4+ (supported in Telegram clients from Feb 2026).
111
+ */
112
+ style(value) {
113
+ this._config.style = value;
114
+ return this;
115
+ }
116
+ /**
117
+ * Shorthand for `.style("danger")` — renders a red button.
118
+ * Ideal for destructive actions like delete, ban, cancel.
119
+ */
120
+ danger() {
121
+ return this.style("danger");
122
+ }
123
+ /**
124
+ * Shorthand for `.style("success")` — renders a green button.
125
+ * Ideal for confirmations like confirm, pay, accept.
126
+ */
127
+ success() {
128
+ return this.style("success");
129
+ }
130
+ /**
131
+ * Shorthand for `.style("primary")` — renders a blue button.
132
+ * Ideal for primary/highlighted actions.
133
+ */
134
+ primary() {
135
+ return this.style("primary");
136
+ }
137
+ /**
138
+ * Set a custom emoji icon to display before the button text.
139
+ * The custom emoji must be owned by the bot's owner (Premium).
140
+ * Requires Telegram Bot API 9.4+.
141
+ * @param customEmojiId - Unique identifier of the custom emoji.
142
+ */
143
+ icon(customEmojiId) {
144
+ this._config.iconCustomEmojiId = customEmojiId;
145
+ return this;
146
+ }
147
+ }
148
+ /**
149
+ * Check if a value is an ActionRef.
150
+ * @internal
151
+ */
152
+ export function isActionRef(value) {
153
+ return (typeof value === "object" &&
154
+ value !== null &&
155
+ value.__Grambot_action === true);
156
+ }
157
+ //# sourceMappingURL=button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.js","sourceRoot":"","sources":["../../src/menu/button.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import type { LayoutBuilderInterface, DynamicLabel, ButtonBuilderInterface, ListBuilderInterface, TextBuilderInterface, ButtonActionHandler, ParseMode } from "../types.js";
2
+ import { ButtonBuilder } from "./button.js";
3
+ import { ListBuilder } from "./list.js";
4
+ /**
5
+ * Describes one element inside the layout (text, button, list, refresh-button).
6
+ * @internal
7
+ */
8
+ export type LayoutElement = {
9
+ kind: "text";
10
+ content: string;
11
+ parseMode?: ParseMode;
12
+ replace?: Record<string, any>;
13
+ } | {
14
+ kind: "image";
15
+ url: string;
16
+ } | {
17
+ kind: "button";
18
+ builder: ButtonBuilder;
19
+ } | {
20
+ kind: "list";
21
+ builder: ListBuilder<any>;
22
+ } | {
23
+ kind: "refresh";
24
+ label: string;
25
+ };
26
+ /**
27
+ * LayoutBuilder — the DSL object passed to `Grambot.menu(layout => { ... })`.
28
+ *
29
+ * Collects declarative descriptions and stores them. The engine
30
+ * later compiles these into real Grammy inline keyboards and handlers.
31
+ */
32
+ export declare class LayoutBuilder implements LayoutBuilderInterface {
33
+ /** @internal */
34
+ readonly _elements: LayoutElement[];
35
+ /** @internal */
36
+ _currentText: string;
37
+ /** @internal */
38
+ _maxPerRow: number;
39
+ /**
40
+ * Set the message text above the keyboard.
41
+ * If called multiple times, appends to the previous text.
42
+ * @param content - The text content.
43
+ */
44
+ text(content: string): TextBuilderInterface;
45
+ /**
46
+ * Set the menu header image.
47
+ * @param url - The image URL.
48
+ */
49
+ image(url: string): void;
50
+ /**
51
+ * Create a button.
52
+ * @param label - A static string or a dynamic `(ctx) => string` function.
53
+ */
54
+ button(label: DynamicLabel): ButtonBuilderInterface;
55
+ /**
56
+ * Create a paginated list of items.
57
+ * @param items - Array of items to display.
58
+ * @param action - Optional default action for items.
59
+ */
60
+ list<T>(items: T[], action?: ButtonActionHandler): ListBuilderInterface<T>;
61
+ /**
62
+ * Maximum number of buttons per row in the final keyboard.
63
+ * 0 (default) means no limit.
64
+ */
65
+ maxPerRow(count: number): void;
66
+ /**
67
+ * Add a "refresh" button that re-renders the current menu.
68
+ * @param label - Button label (e.g., "🔄 Refresh").
69
+ */
70
+ refreshButton(label: string): void;
71
+ }
72
+ /**
73
+ * Helper for configuring message text (e.g., parse mode).
74
+ * @internal
75
+ */
76
+ export declare class TextBuilder implements TextBuilderInterface {
77
+ private element;
78
+ constructor(element: Extract<LayoutElement, {
79
+ kind: "text";
80
+ }>);
81
+ /** Set the parse mode for this text block. */
82
+ parseAs(mode: ParseMode): TextBuilderInterface;
83
+ /** Set interpolation variables for the text */
84
+ replace(data: Record<string, any>): TextBuilderInterface;
85
+ }
86
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/menu/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,YAAY,EACZ,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,SAAS,EACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC;;;GAGG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GACvF;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,sBAAsB;IAC1D,gBAAgB;IAChB,QAAQ,CAAC,SAAS,EAAE,aAAa,EAAE,CAAM;IACzC,gBAAgB;IAChB,YAAY,SAAM;IAClB,gBAAgB;IAChB,UAAU,SAAK;IAEf;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,oBAAoB;IAO3C;;;OAGG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxB;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,sBAAsB;IAMnD;;;;OAIG;IACH,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,mBAAmB,GAAG,oBAAoB,CAAC,CAAC,CAAC;IAO1E;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI9B;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAGnC;AAED;;;GAGG;AACH,qBAAa,WAAY,YAAW,oBAAoB;IAC1C,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAErE,8CAA8C;IAC9C,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,oBAAoB;IAK9C,+CAA+C;IAC/C,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,oBAAoB;CAIzD"}
@@ -0,0 +1,90 @@
1
+ import { ButtonBuilder } from "./button.js";
2
+ import { ListBuilder } from "./list.js";
3
+ /**
4
+ * LayoutBuilder — the DSL object passed to `Grambot.menu(layout => { ... })`.
5
+ *
6
+ * Collects declarative descriptions and stores them. The engine
7
+ * later compiles these into real Grammy inline keyboards and handlers.
8
+ */
9
+ export class LayoutBuilder {
10
+ /** @internal */
11
+ _elements = [];
12
+ /** @internal */
13
+ _currentText = "";
14
+ /** @internal */
15
+ _maxPerRow = 0; // 0 = no limit
16
+ /**
17
+ * Set the message text above the keyboard.
18
+ * If called multiple times, appends to the previous text.
19
+ * @param content - The text content.
20
+ */
21
+ text(content) {
22
+ this._currentText = content;
23
+ const element = { kind: "text", content };
24
+ this._elements.push(element);
25
+ return new TextBuilder(element);
26
+ }
27
+ /**
28
+ * Set the menu header image.
29
+ * @param url - The image URL.
30
+ */
31
+ image(url) {
32
+ this._elements.push({ kind: "image", url });
33
+ }
34
+ /**
35
+ * Create a button.
36
+ * @param label - A static string or a dynamic `(ctx) => string` function.
37
+ */
38
+ button(label) {
39
+ const builder = new ButtonBuilder(label);
40
+ this._elements.push({ kind: "button", builder });
41
+ return builder;
42
+ }
43
+ /**
44
+ * Create a paginated list of items.
45
+ * @param items - Array of items to display.
46
+ * @param action - Optional default action for items.
47
+ */
48
+ list(items, action) {
49
+ const builder = new ListBuilder(items);
50
+ if (action)
51
+ builder.action(action);
52
+ this._elements.push({ kind: "list", builder });
53
+ return builder;
54
+ }
55
+ /**
56
+ * Maximum number of buttons per row in the final keyboard.
57
+ * 0 (default) means no limit.
58
+ */
59
+ maxPerRow(count) {
60
+ this._maxPerRow = count;
61
+ }
62
+ /**
63
+ * Add a "refresh" button that re-renders the current menu.
64
+ * @param label - Button label (e.g., "🔄 Refresh").
65
+ */
66
+ refreshButton(label) {
67
+ this._elements.push({ kind: "refresh", label });
68
+ }
69
+ }
70
+ /**
71
+ * Helper for configuring message text (e.g., parse mode).
72
+ * @internal
73
+ */
74
+ export class TextBuilder {
75
+ element;
76
+ constructor(element) {
77
+ this.element = element;
78
+ }
79
+ /** Set the parse mode for this text block. */
80
+ parseAs(mode) {
81
+ this.element.parseMode = mode;
82
+ return this;
83
+ }
84
+ /** Set interpolation variables for the text */
85
+ replace(data) {
86
+ this.element.replace = data;
87
+ return this;
88
+ }
89
+ }
90
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/menu/layout.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAaxC;;;;;GAKG;AACH,MAAM,OAAO,aAAa;IACxB,gBAAgB;IACP,SAAS,GAAoB,EAAE,CAAC;IACzC,gBAAgB;IAChB,YAAY,GAAG,EAAE,CAAC;IAClB,gBAAgB;IAChB,UAAU,GAAG,CAAC,CAAC,CAAC,eAAe;IAE/B;;;;OAIG;IACH,IAAI,CAAC,OAAe;QAClB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;QAC5B,MAAM,OAAO,GAA6C,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QACpF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,GAAW;QACf,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAmB;QACxB,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAI,KAAU,EAAE,MAA4B;QAC9C,MAAM,OAAO,GAAG,IAAI,WAAW,CAAI,KAAK,CAAC,CAAC;QAC1C,IAAI,MAAM;YAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/C,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,SAAS,CAAC,KAAa;QACrB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,KAAa;QACzB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,WAAW;IACF;IAApB,YAAoB,OAAiD;QAAjD,YAAO,GAAP,OAAO,CAA0C;IAAG,CAAC;IAEzE,8CAA8C;IAC9C,OAAO,CAAC,IAAe;QACrB,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+CAA+C;IAC/C,OAAO,CAAC,IAAyB;QAC/B,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,43 @@
1
+ import type { ListConfig, ListBuilderInterface, ButtonBuilderInterface, ButtonActionHandler } from "../types.js";
2
+ /**
3
+ * Fluent builder for a paginated, dynamic list of items rendered as buttons.
4
+ *
5
+ * Usage (from LayoutBuilder):
6
+ * ```ts
7
+ * layout.list(items)
8
+ * .perPage(5)
9
+ * .columns(1)
10
+ * .render(item => layout.button(`⭐ ${item.title}`).payload(...).action(...))
11
+ * ```
12
+ */
13
+ export declare class ListBuilder<T> implements ListBuilderInterface<T> {
14
+ /** @internal */
15
+ readonly _config: ListConfig<T>;
16
+ /**
17
+ * @internal Use `layout.list()` instead.
18
+ */
19
+ constructor(items: T[]);
20
+ /**
21
+ * Set the number of items to show per page.
22
+ * Default is 10.
23
+ */
24
+ perPage(count: number): this;
25
+ /**
26
+ * Set the number of columns (buttons per row) for the list items.
27
+ * Default is 1.
28
+ */
29
+ columns(count: number): this;
30
+ /**
31
+ * Set the render callback — called once per visible item on the current page.
32
+ *
33
+ * The callback must return a {@link ButtonBuilderInterface}.
34
+ * @param fn - A function that returns a button builder for each item.
35
+ */
36
+ render(fn: (item: T) => ButtonBuilderInterface): void;
37
+ /**
38
+ * Set the default action for items in this list.
39
+ * @param handler - The action handler or reference.
40
+ */
41
+ action(handler: ButtonActionHandler): this;
42
+ }
43
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/menu/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;GAUG;AACH,qBAAa,WAAW,CAAC,CAAC,CAAE,YAAW,oBAAoB,CAAC,CAAC,CAAC;IAC5D,gBAAgB;IAChB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IAEhC;;OAEG;gBACS,KAAK,EAAE,CAAC,EAAE;IAStB;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK5B;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK5B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,sBAAsB,GAAG,IAAI;IAIrD;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI;CAI3C"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Fluent builder for a paginated, dynamic list of items rendered as buttons.
3
+ *
4
+ * Usage (from LayoutBuilder):
5
+ * ```ts
6
+ * layout.list(items)
7
+ * .perPage(5)
8
+ * .columns(1)
9
+ * .render(item => layout.button(`⭐ ${item.title}`).payload(...).action(...))
10
+ * ```
11
+ */
12
+ export class ListBuilder {
13
+ /** @internal */
14
+ _config;
15
+ /**
16
+ * @internal Use `layout.list()` instead.
17
+ */
18
+ constructor(items) {
19
+ this._config = {
20
+ items,
21
+ itemsPerPage: 10,
22
+ columns: 1,
23
+ renderFn: undefined,
24
+ };
25
+ }
26
+ /**
27
+ * Set the number of items to show per page.
28
+ * Default is 10.
29
+ */
30
+ perPage(count) {
31
+ this._config.itemsPerPage = count;
32
+ return this;
33
+ }
34
+ /**
35
+ * Set the number of columns (buttons per row) for the list items.
36
+ * Default is 1.
37
+ */
38
+ columns(count) {
39
+ this._config.columns = count;
40
+ return this;
41
+ }
42
+ /**
43
+ * Set the render callback — called once per visible item on the current page.
44
+ *
45
+ * The callback must return a {@link ButtonBuilderInterface}.
46
+ * @param fn - A function that returns a button builder for each item.
47
+ */
48
+ render(fn) {
49
+ this._config.renderFn = fn;
50
+ }
51
+ /**
52
+ * Set the default action for items in this list.
53
+ * @param handler - The action handler or reference.
54
+ */
55
+ action(handler) {
56
+ this._config.action = handler;
57
+ return this;
58
+ }
59
+ }
60
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/menu/list.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,WAAW;IACtB,gBAAgB;IACP,OAAO,CAAgB;IAEhC;;OAEG;IACH,YAAY,KAAU;QACpB,IAAI,CAAC,OAAO,GAAG;YACb,KAAK;YACL,YAAY,EAAE,EAAE;YAChB,OAAO,EAAE,CAAC;YACV,QAAQ,EAAE,SAAS;SACpB,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,KAAa;QACnB,IAAI,CAAC,OAAO,CAAC,YAAY,GAAG,KAAK,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,KAAa;QACnB,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,EAAuC;QAC5C,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,EAAE,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,OAA4B;QACjC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ import type { LayoutBuilderInterface, MenuRef, GrambotContext } from "../types.js";
2
+ import { LayoutBuilder } from "./layout.js";
3
+ export { LayoutBuilder } from "./layout.js";
4
+ export { ButtonBuilder } from "./button.js";
5
+ export { ListBuilder } from "./list.js";
6
+ /**
7
+ * Returns all menus created via createMenu().
8
+ * @internal
9
+ */
10
+ export declare function getGlobalMenus(): MenuRef[];
11
+ /**
12
+ * Creates a MenuRef — a serializable reference to a menu definition.
13
+ *
14
+ * The builder function is stored and will be called when the menu
15
+ * needs to be rendered (at compile time or on refresh).
16
+ *
17
+ * @param builder - A function that defines the menu layout.
18
+ * @param options - Optional configuration like a fixed manual ID.
19
+ * @returns A {@link MenuRef} object.
20
+ */
21
+ export declare function createMenu(builder: (layout: LayoutBuilderInterface, ctx: GrambotContext) => void | Promise<void>, options?: {
22
+ id?: string;
23
+ }): MenuRef;
24
+ /**
25
+ * Compile a MenuRef into a LayoutBuilder (runs the builder function).
26
+ * @internal
27
+ */
28
+ export declare function compileMenu(ref: MenuRef, ctx: GrambotContext): Promise<LayoutBuilder>;
29
+ //# sourceMappingURL=menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../src/menu/menu.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,sBAAsB,EACtB,OAAO,EACP,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAIxC;;;GAGG;AACH,wBAAgB,cAAc,IAAI,OAAO,EAAE,CAE1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,CAAC,MAAM,EAAE,sBAAsB,EAAE,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EACtF,OAAO,CAAC,EAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GACxB,OAAO,CAqCT;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAI3F"}
@@ -0,0 +1,73 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { LayoutBuilder } from "./layout.js";
3
+ export { LayoutBuilder } from "./layout.js";
4
+ export { ButtonBuilder } from "./button.js";
5
+ export { ListBuilder } from "./list.js";
6
+ const globalMenus = new Set();
7
+ /**
8
+ * Returns all menus created via createMenu().
9
+ * @internal
10
+ */
11
+ export function getGlobalMenus() {
12
+ return Array.from(globalMenus);
13
+ }
14
+ /**
15
+ * Creates a MenuRef — a serializable reference to a menu definition.
16
+ *
17
+ * The builder function is stored and will be called when the menu
18
+ * needs to be rendered (at compile time or on refresh).
19
+ *
20
+ * @param builder - A function that defines the menu layout.
21
+ * @param options - Optional configuration like a fixed manual ID.
22
+ * @returns A {@link MenuRef} object.
23
+ */
24
+ export function createMenu(builder, options) {
25
+ const ref = {
26
+ __Grambot_menu: true,
27
+ id: options?.id ?? `m${randomUUID().slice(0, 6)}`,
28
+ builder,
29
+ triggers: {},
30
+ /**
31
+ * Add a command trigger to open this menu.
32
+ * @param name - Command name (e.g., "start").
33
+ */
34
+ command(name) {
35
+ if (!this.triggers)
36
+ this.triggers = {};
37
+ this.triggers.commands = [...(this.triggers.commands || []), name];
38
+ return this;
39
+ },
40
+ /**
41
+ * Add a word/phrase trigger to open this menu.
42
+ * @param text - Exact text to match.
43
+ */
44
+ word(text) {
45
+ if (!this.triggers)
46
+ this.triggers = {};
47
+ this.triggers.words = [...(this.triggers.words || []), text];
48
+ return this;
49
+ },
50
+ /**
51
+ * Add a regex trigger to open this menu.
52
+ * @param pattern - Regular expression to match.
53
+ */
54
+ regexp(pattern) {
55
+ if (!this.triggers)
56
+ this.triggers = {};
57
+ this.triggers.regexps = [...(this.triggers.regexps || []), pattern];
58
+ return this;
59
+ },
60
+ };
61
+ globalMenus.add(ref);
62
+ return ref;
63
+ }
64
+ /**
65
+ * Compile a MenuRef into a LayoutBuilder (runs the builder function).
66
+ * @internal
67
+ */
68
+ export async function compileMenu(ref, ctx) {
69
+ const layout = new LayoutBuilder();
70
+ await ref.builder(layout, ctx);
71
+ return layout;
72
+ }
73
+ //# sourceMappingURL=menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/menu/menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAMzC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAW,CAAC;AAEvC;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CACxB,OAAsF,EACtF,OAAyB;IAEzB,MAAM,GAAG,GAAY;QACnB,cAAc,EAAE,IAAI;QACpB,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,IAAI,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QACjD,OAAO;QACP,QAAQ,EAAE,EAAE;QACZ;;;WAGG;QACH,OAAO,CAAC,IAAY;YAClB,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,QAAQ,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YACnE,OAAO,IAAI,CAAC;QACd,CAAC;QACD;;;WAGG;QACH,IAAI,CAAC,IAAY;YACf,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YAC7D,OAAO,IAAI,CAAC;QACd,CAAC;QACD;;;WAGG;QACH,MAAM,CAAC,OAAe;YACpB,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;YACpE,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;IAEF,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAY,EAAE,GAAmB;IACjE,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;IACnC,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC;AAChB,CAAC"}