telekit-lib 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.
package/PUBLISHING.md ADDED
@@ -0,0 +1,52 @@
1
+ # 🚀 Руководство по публикации TeleKit
2
+
3
+ Это руководство объясняет, как опубликовать вашу библиотеку в NPM, на GitHub и разместить документацию.
4
+
5
+ ## 1. Подготовка к NPM
6
+
7
+ 1. **Войдите в NPM** (если еще не вошли):
8
+ ```bash
9
+ npm login
10
+ ```
11
+ 2. **Соберите проект**:
12
+ ```bash
13
+ npm run build
14
+ ```
15
+ *Это создаст папку `dist`, которая и будет опубликована.*
16
+ 3. **Опубликуйте**:
17
+ ```bash
18
+ npm publish --access public
19
+ ```
20
+ *Убедитесь, что версия в `package.json` уникальна (например, 2.0.0).*
21
+
22
+ ## 2. Отправка на GitHub
23
+
24
+ 1. **Инициализируйте Git**:
25
+ ```bash
26
+ git init
27
+ git add .
28
+ git commit -m "Initial commit of TeleKit 2.0"
29
+ ```
30
+ 2. **Отправьте (Push)**:
31
+ ```bash
32
+ git remote add origin https://github.com/TaHel-UDev/telekit.git
33
+ git branch -M main
34
+ git push -u origin main
35
+ ```
36
+
37
+ ## 3. Хостинг документации (Landing Page)
38
+
39
+ У вас есть красивая документация в стиле "Shadcn" в папке `docs/`.
40
+
41
+ **Вариант А: GitHub Pages (Самый простой)**
42
+ 1. Перейдите в настройки репозитория (Repository Settings) > Pages.
43
+ 2. Выберите источник: **Deploy from branch**.
44
+ 3. Ветка: `main`, Папка: `/docs`.
45
+ 4. Нажмите **Save**. Ваш сайт будет доступен по адресу `https://tahel-udev.github.io/telekit/` через несколько минут.
46
+
47
+ **Вариант Б: Netlify / Vercel**
48
+ 1. Перетащите папку `docs` в Netlify Drop.
49
+ 2. Мгновенное развертывание.
50
+
51
+ ---
52
+ *Автор TaHel-UDev*
@@ -0,0 +1,52 @@
1
+ # Инструкция по публикации библиотеки в NPM
2
+
3
+ Чтобы вашей библиотекой могли пользоваться другие люди (устанавливать через `npm install easy-tg-bot-lib`), её нужно опубликовать в реестре NPM.
4
+
5
+ ## Шаг 1: Подготовка
6
+ 1. Убедитесь, что код скомпилирован:
7
+ ```bash
8
+ npm run build
9
+ ```
10
+ 2. Убедитесь, что в `package.json` поле `main` указывает на `dist/index.js`, а `types` на `dist/index.d.ts`. Это уже настроено.
11
+ 3. (Опционально) Создайте файл `.npmignore`, чтобы не отправлять в NPM лишние файлы (исходники, конфиги), оставив только папку `dist` и `package.json`.
12
+ Содержимое `.npmignore`:
13
+ ```
14
+ src/
15
+ tsconfig.json
16
+ examples/
17
+ ```
18
+
19
+ ## Шаг 2: Регистрация в NPM
20
+ Если у вас еще нет аккаунта:
21
+ 1. Перейдите на [npmjs.com](https://www.npmjs.com/) и зарегистрируйтесь.
22
+ 2. В терминале выполните вход:
23
+ ```bash
24
+ npm login
25
+ ```
26
+ Следуйте инструкциям (ввод username, password, email).
27
+
28
+ ## Шаг 3: Публикация
29
+ 1. **Важно**: Имя пакета в `package.json` (`"name": "easy-tg-bot-lib"`) должно быть уникальным во всем NPM. Скорее всего, простые имена уже заняты.
30
+ - Рекомендуется использовать scope (пространство имен), например `@ваш-ник/easy-bot`.
31
+ - Для этого измените имя в `package.json` на `@ваш-ник/easy-bot`.
32
+ 2. Выполните команду:
33
+ ```bash
34
+ npm publish --access public
35
+ ```
36
+ (Флаг `--access public` обязателен для scoped-пакетов, так как по умолчанию они считаются приватными и требуют платной подписки).
37
+
38
+ ## Шаг 4: Обновление версий
39
+ Когда вы внесете изменения в код:
40
+ 1. Измените версию в `package.json` (например, с `1.0.0` на `1.0.1`).
41
+ 2. Снова выполните `npm run build`.
42
+ 3. Снова выполните `npm publish`.
43
+
44
+ ## Как будут устанавливать вашу библиотеку
45
+ Пользователи будут писать:
46
+ ```bash
47
+ npm install @ваш-ник/easy-bot
48
+ ```
49
+ И использовать:
50
+ ```typescript
51
+ import { EasyBot } from '@ваш-ник/easy-bot';
52
+ ```
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # TeleKit Framework ⚡
2
+
3
+ **Профессиональный TypeScript фреймворк для Telegram ботов**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/telekit-lib.svg)](https://www.npmjs.com/package/telekit-lib)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ TeleKit — это идеальный инструмент для создания Telegram ботов. Он сочетает в себе архитектуру корпоративного уровня с простотой, доступной для новичков.
9
+
10
+ ## ✨ Особенности
11
+
12
+ - **LocalDB**: Встроенная JSON NoSQL база данных. Не нужно настраивать Mongo или SQL для старта.
13
+ - **Строгая типизация**: Полная поддержка TypeScript.
14
+ - **Сцены и Визарды**: Легкое создание многошаговых форм.
15
+ - **Клавиатуры**: Простой конструктор разметки.
16
+ - **Адаптеры**: Простое подключение к Redis/Postgres.
17
+
18
+ ## 📦 Установка
19
+
20
+ ```bash
21
+ npm install telekit-lib
22
+ ```
23
+
24
+ ## 📖 Документация
25
+
26
+ Полная документация доступна в папке [`docs/`](./docs). Откройте `docs/index.html` в вашем браузере.
27
+
28
+ ## ⚡ Быстрый старт
29
+
30
+ ```typescript
31
+ import { TeleKit, LocalDB } from 'telekit-lib';
32
+
33
+ const bot = new TeleKit(process.env.TOKEN);
34
+ const db = new LocalDB('users.json');
35
+
36
+ bot.command('start', (ctx) => {
37
+ db.push({ id: ctx.from.id, name: ctx.from.first_name });
38
+ ctx.reply('Добро пожаловать в TeleKit!');
39
+ });
40
+
41
+ bot.start();
42
+ ```
43
+
44
+ ---
45
+ *Создано TaHel-UDev*
@@ -0,0 +1,117 @@
1
+ import { Update, User, InlineKeyboardButton, ReplyKeyboardMarkup, InlineKeyboardMarkup } from 'typegram';
2
+ export * from 'typegram';
3
+ export type Handler = (ctx: Context) => void | Promise<void>;
4
+ export type Middleware = (ctx: Context, next: () => Promise<void>) => Promise<void>;
5
+ interface SessionContainer {
6
+ [key: string]: any;
7
+ }
8
+ /**
9
+ * Простая, но мощная JSON база данных.
10
+ * Позволяет хранить массивы данных с поиском и фильтрацией.
11
+ */
12
+ export declare class LocalDB<T extends object> {
13
+ private filePath;
14
+ private data;
15
+ constructor(filename: string);
16
+ private load;
17
+ private save;
18
+ /** Добавить запись */
19
+ push(item: T): Promise<void>;
20
+ /** Найти одну запись */
21
+ findOne(predicate: (item: T) => boolean): Promise<T | null>;
22
+ /** Найти все подходящие записи */
23
+ find(predicate: (item: T) => boolean): Promise<T[]>;
24
+ /** Обновить запись (находим и меняем поля) */
25
+ update(predicate: (item: T) => boolean, updates: Partial<T>): Promise<boolean>;
26
+ /** Удалить запись */
27
+ delete(predicate: (item: T) => boolean): Promise<void>;
28
+ /** Получить все записи */
29
+ getAll(): T[];
30
+ }
31
+ export interface ISessionStore {
32
+ get(key: string): Promise<any | null>;
33
+ set(key: string, value: any): Promise<void>;
34
+ delete(key: string): Promise<void>;
35
+ }
36
+ export declare class MemoryStore implements ISessionStore {
37
+ private store;
38
+ get(key: string): Promise<any>;
39
+ set(key: string, value: any): Promise<void>;
40
+ delete(key: string): Promise<void>;
41
+ }
42
+ export declare class FileStore implements ISessionStore {
43
+ private filePath;
44
+ constructor(filename?: string);
45
+ get(key: string): Promise<any>;
46
+ set(key: string, value: any): Promise<void>;
47
+ delete(key: string): Promise<void>;
48
+ }
49
+ export declare class Scene {
50
+ id: string;
51
+ steps: Handler[];
52
+ constructor(id: string, ...steps: Handler[]);
53
+ }
54
+ export declare class Keyboard {
55
+ static reply(buttons: (string | string[])[], options?: {
56
+ resize_keyboard?: boolean;
57
+ one_time_keyboard?: boolean;
58
+ }): ReplyKeyboardMarkup;
59
+ static inline(rows: InlineKeyboardButton[][]): InlineKeyboardMarkup;
60
+ static callback(text: string, data: string): InlineKeyboardButton;
61
+ static url(text: string, url: string): InlineKeyboardButton;
62
+ static remove(): {
63
+ remove_keyboard: boolean;
64
+ };
65
+ }
66
+ export declare class Context {
67
+ update: Update;
68
+ bot: TeleKit;
69
+ session: SessionContainer;
70
+ constructor(update: Update, bot: TeleKit, session: SessionContainer);
71
+ get chatId(): number | undefined;
72
+ get from(): User | undefined;
73
+ get text(): string | undefined;
74
+ get callbackData(): string | undefined;
75
+ reply(text: string, extra?: any): Promise<any>;
76
+ answerCallback(text?: string, alert?: boolean): Promise<any>;
77
+ editMessageText(text: string, extra?: any): Promise<any>;
78
+ deleteMessage(): Promise<any>;
79
+ enter(sceneId: string): void;
80
+ next(): void;
81
+ leave(): void;
82
+ }
83
+ export declare class TelegramApi {
84
+ private client;
85
+ constructor(token: string);
86
+ call(method: string, data?: any): Promise<any>;
87
+ sendMessage(params: any): Promise<any>;
88
+ }
89
+ export declare class TeleKit {
90
+ api: TelegramApi;
91
+ storage: ISessionStore;
92
+ scenes: Map<string, Scene>;
93
+ private token;
94
+ private offset;
95
+ private isPolling;
96
+ private middlewares;
97
+ private commands;
98
+ private textPatterns;
99
+ private callbackPatterns;
100
+ private fallbackHandler;
101
+ constructor(token: string, options?: {
102
+ store?: ISessionStore;
103
+ });
104
+ setCommands(commands: {
105
+ command: string;
106
+ description: string;
107
+ }[]): Promise<any>;
108
+ use(middleware: Middleware): void;
109
+ addScene(scene: Scene): void;
110
+ command(cmd: string, handler: Handler): void;
111
+ onText(trigger: string | RegExp, handler: Handler): void;
112
+ onCallback(trigger: string | RegExp, handler: Handler): void;
113
+ onMessage(handler: Handler): void;
114
+ start(): Promise<void>;
115
+ private loop;
116
+ private handleUpdate;
117
+ }
package/dist/index.js ADDED
@@ -0,0 +1,356 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
36
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
37
+ };
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.TeleKit = exports.TelegramApi = exports.Context = exports.Keyboard = exports.Scene = exports.FileStore = exports.MemoryStore = exports.LocalDB = void 0;
43
+ const axios_1 = __importDefault(require("axios"));
44
+ const fs = __importStar(require("fs"));
45
+ const path = __importStar(require("path"));
46
+ __exportStar(require("typegram"), exports);
47
+ // --- 📦 LOCAL DB SYSTEM (Встроенная база) ---
48
+ /**
49
+ * Простая, но мощная JSON база данных.
50
+ * Позволяет хранить массивы данных с поиском и фильтрацией.
51
+ */
52
+ class LocalDB {
53
+ constructor(filename) {
54
+ this.data = [];
55
+ this.filePath = path.resolve(process.cwd(), filename);
56
+ this.load();
57
+ }
58
+ load() {
59
+ if (!fs.existsSync(this.filePath)) {
60
+ this.save();
61
+ return;
62
+ }
63
+ try {
64
+ this.data = JSON.parse(fs.readFileSync(this.filePath, 'utf-8'));
65
+ }
66
+ catch (e) {
67
+ console.error(`Ошибка чтения БД ${this.filePath}:`, e);
68
+ this.data = [];
69
+ }
70
+ }
71
+ save() {
72
+ fs.writeFileSync(this.filePath, JSON.stringify(this.data, null, 2));
73
+ }
74
+ // --- Public API ---
75
+ /** Добавить запись */
76
+ async push(item) {
77
+ this.data.push(item);
78
+ this.save();
79
+ }
80
+ /** Найти одну запись */
81
+ async findOne(predicate) {
82
+ return this.data.find(predicate) || null;
83
+ }
84
+ /** Найти все подходящие записи */
85
+ async find(predicate) {
86
+ return this.data.filter(predicate);
87
+ }
88
+ /** Обновить запись (находим и меняем поля) */
89
+ async update(predicate, updates) {
90
+ const item = this.data.find(predicate);
91
+ if (item) {
92
+ Object.assign(item, updates);
93
+ this.save();
94
+ return true;
95
+ }
96
+ return false;
97
+ }
98
+ /** Удалить запись */
99
+ async delete(predicate) {
100
+ const initLength = this.data.length;
101
+ this.data = this.data.filter(item => !predicate(item));
102
+ if (this.data.length !== initLength)
103
+ this.save();
104
+ }
105
+ /** Получить все записи */
106
+ getAll() {
107
+ return [...this.data];
108
+ }
109
+ }
110
+ exports.LocalDB = LocalDB;
111
+ class MemoryStore {
112
+ constructor() {
113
+ this.store = new Map();
114
+ }
115
+ async get(key) { return this.store.get(key) || null; }
116
+ async set(key, value) { this.store.set(key, value); }
117
+ async delete(key) { this.store.delete(key); }
118
+ }
119
+ exports.MemoryStore = MemoryStore;
120
+ class FileStore {
121
+ constructor(filename = 'sessions.json') {
122
+ this.filePath = path.resolve(process.cwd(), filename);
123
+ }
124
+ async get(key) {
125
+ if (!fs.existsSync(this.filePath))
126
+ return null;
127
+ try {
128
+ const d = JSON.parse(fs.readFileSync(this.filePath, 'utf-8'));
129
+ return d[key] || null;
130
+ }
131
+ catch {
132
+ return null;
133
+ }
134
+ }
135
+ async set(key, value) {
136
+ let d = {};
137
+ if (fs.existsSync(this.filePath)) {
138
+ try {
139
+ d = JSON.parse(fs.readFileSync(this.filePath, 'utf-8'));
140
+ }
141
+ catch { }
142
+ }
143
+ d[key] = value;
144
+ fs.writeFileSync(this.filePath, JSON.stringify(d, null, 2));
145
+ }
146
+ async delete(key) {
147
+ if (!fs.existsSync(this.filePath))
148
+ return;
149
+ const d = JSON.parse(fs.readFileSync(this.filePath, 'utf-8'));
150
+ delete d[key];
151
+ fs.writeFileSync(this.filePath, JSON.stringify(d, null, 2));
152
+ }
153
+ }
154
+ exports.FileStore = FileStore;
155
+ // --- Классы ---
156
+ class Scene {
157
+ constructor(id, ...steps) { this.id = id; this.steps = steps; }
158
+ }
159
+ exports.Scene = Scene;
160
+ class Keyboard {
161
+ static reply(buttons, options = { resize_keyboard: true }) {
162
+ const keyboard = buttons.map(row => {
163
+ if (typeof row === 'string')
164
+ return [{ text: row }];
165
+ return row.map(text => ({ text }));
166
+ });
167
+ return { keyboard, ...options };
168
+ }
169
+ static inline(rows) { return { inline_keyboard: rows }; }
170
+ static callback(text, data) { return { text, callback_data: data }; }
171
+ static url(text, url) { return { text, url }; }
172
+ static remove() { return { remove_keyboard: true }; }
173
+ }
174
+ exports.Keyboard = Keyboard;
175
+ class Context {
176
+ constructor(update, bot, session) {
177
+ this.update = update;
178
+ this.bot = bot;
179
+ this.session = session;
180
+ }
181
+ get chatId() {
182
+ if ('message' in this.update)
183
+ return this.update.message.chat.id;
184
+ if ('callback_query' in this.update)
185
+ return this.update.callback_query.message?.chat.id;
186
+ return undefined;
187
+ }
188
+ get from() {
189
+ if ('message' in this.update)
190
+ return this.update.message.from;
191
+ if ('callback_query' in this.update)
192
+ return this.update.callback_query.from;
193
+ return undefined;
194
+ }
195
+ get text() {
196
+ if ('message' in this.update && 'text' in this.update.message)
197
+ return this.update.message.text;
198
+ return undefined;
199
+ }
200
+ get callbackData() {
201
+ if ('callback_query' in this.update && 'data' in this.update.callback_query)
202
+ return this.update.callback_query.data;
203
+ return undefined;
204
+ }
205
+ async reply(text, extra = {}) {
206
+ if (!this.chatId)
207
+ return;
208
+ return this.bot.api.sendMessage({ chat_id: this.chatId, text, ...extra });
209
+ }
210
+ async answerCallback(text, alert = false) {
211
+ if (!('callback_query' in this.update))
212
+ return;
213
+ return this.bot.api.call('answerCallbackQuery', { callback_query_id: this.update.callback_query.id, text, show_alert: alert });
214
+ }
215
+ async editMessageText(text, extra = {}) {
216
+ if (!('callback_query' in this.update) || !this.update.callback_query.message)
217
+ return;
218
+ const msg = this.update.callback_query.message;
219
+ return this.bot.api.call('editMessageText', { chat_id: msg.chat.id, message_id: msg.message_id, text, ...extra });
220
+ }
221
+ async deleteMessage() {
222
+ if (this.chatId) {
223
+ const msgId = 'message' in this.update
224
+ ? this.update.message.message_id
225
+ : ('callback_query' in this.update ? this.update.callback_query.message?.message_id : undefined);
226
+ if (msgId)
227
+ return this.bot.api.call('deleteMessage', { chat_id: this.chatId, message_id: msgId });
228
+ }
229
+ }
230
+ enter(sceneId) {
231
+ this.session.__scene = { currentSceneId: sceneId, currentStep: 0, data: {} };
232
+ const scene = this.bot.scenes.get(sceneId);
233
+ if (scene && scene.steps.length > 0)
234
+ scene.steps[0](this);
235
+ }
236
+ next() { if (this.session.__scene)
237
+ this.session.__scene.currentStep++; }
238
+ leave() { this.session.__scene = null; }
239
+ }
240
+ exports.Context = Context;
241
+ class TelegramApi {
242
+ constructor(token) { this.client = axios_1.default.create({ baseURL: `https://api.telegram.org/bot${token}/`, timeout: 40000 }); }
243
+ async call(method, data = {}) {
244
+ try {
245
+ const res = await this.client.post(method, data);
246
+ if (!res.data.ok)
247
+ throw new Error(res.data.description);
248
+ return res.data.result;
249
+ }
250
+ catch (e) {
251
+ console.error(`API Error [${method}]:`, e.message);
252
+ return null;
253
+ }
254
+ }
255
+ async sendMessage(params) { return this.call('sendMessage', params); }
256
+ }
257
+ exports.TelegramApi = TelegramApi;
258
+ class TeleKit {
259
+ constructor(token, options = {}) {
260
+ this.scenes = new Map();
261
+ this.offset = 0;
262
+ this.isPolling = false;
263
+ this.middlewares = [];
264
+ this.commands = new Map();
265
+ this.textPatterns = new Map();
266
+ this.callbackPatterns = new Map();
267
+ this.fallbackHandler = null;
268
+ this.token = token;
269
+ this.api = new TelegramApi(token);
270
+ this.storage = options.store || new MemoryStore();
271
+ }
272
+ async setCommands(commands) { return this.api.call('setMyCommands', { commands }); }
273
+ use(middleware) { this.middlewares.push(middleware); }
274
+ addScene(scene) { this.scenes.set(scene.id, scene); }
275
+ command(cmd, handler) { this.commands.set(cmd.replace('/', ''), handler); }
276
+ onText(trigger, handler) { this.textPatterns.set(trigger, handler); }
277
+ onCallback(trigger, handler) { this.callbackPatterns.set(trigger, handler); }
278
+ onMessage(handler) { this.fallbackHandler = handler; }
279
+ async start() {
280
+ this.isPolling = true;
281
+ console.log('⚡ TeleKit Bot started...');
282
+ this.loop();
283
+ }
284
+ async loop() {
285
+ if (!this.isPolling)
286
+ return;
287
+ try {
288
+ const updates = await this.api.call('getUpdates', { offset: this.offset, timeout: 30 });
289
+ if (updates && Array.isArray(updates)) {
290
+ for (const update of updates) {
291
+ this.offset = update.update_id + 1;
292
+ await this.handleUpdate(update);
293
+ }
294
+ }
295
+ }
296
+ catch (e) {
297
+ await new Promise(r => setTimeout(r, 3000));
298
+ }
299
+ if (this.isPolling)
300
+ this.loop();
301
+ }
302
+ async handleUpdate(update) {
303
+ let userId;
304
+ if ('message' in update)
305
+ userId = update.message.from?.id;
306
+ else if ('callback_query' in update)
307
+ userId = update.callback_query.from.id;
308
+ if (!userId)
309
+ return;
310
+ const sessionKey = `session:${userId}`;
311
+ let sessionData = await this.storage.get(sessionKey) || {};
312
+ const ctx = new Context(update, this, sessionData);
313
+ let handled = false;
314
+ for (const mw of this.middlewares)
315
+ await mw(ctx, async () => { });
316
+ if (ctx.session.__scene) {
317
+ const s = ctx.session.__scene;
318
+ const scene = this.scenes.get(s.currentSceneId);
319
+ if (scene && scene.steps[s.currentStep]) {
320
+ await scene.steps[s.currentStep](ctx);
321
+ handled = true;
322
+ }
323
+ }
324
+ if (!handled) {
325
+ if (ctx.callbackData) {
326
+ for (const [t, h] of this.callbackPatterns)
327
+ if (typeof t === 'string' ? ctx.callbackData === t : t.test(ctx.callbackData)) {
328
+ await h(ctx);
329
+ handled = true;
330
+ break;
331
+ }
332
+ }
333
+ if (!handled && ctx.text) {
334
+ if (ctx.text.startsWith('/')) {
335
+ const cmd = ctx.text.split(' ')[0].substring(1);
336
+ if (this.commands.has(cmd)) {
337
+ await this.commands.get(cmd)(ctx);
338
+ handled = true;
339
+ }
340
+ }
341
+ if (!handled) {
342
+ for (const [t, h] of this.textPatterns)
343
+ if (typeof t === 'string' ? ctx.text === t : t.test(ctx.text)) {
344
+ await h(ctx);
345
+ handled = true;
346
+ break;
347
+ }
348
+ }
349
+ }
350
+ if (!handled && this.fallbackHandler && ctx.text)
351
+ await this.fallbackHandler(ctx);
352
+ }
353
+ await this.storage.set(sessionKey, ctx.session);
354
+ }
355
+ }
356
+ exports.TeleKit = TeleKit;