@ai-devkit/channel-connector 0.13.3 → 0.13.4

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 (69) hide show
  1. package/dist/ChannelConfigRepository.d.ts +1 -1
  2. package/dist/ChannelConfigRepository.d.ts.map +1 -1
  3. package/dist/ChannelConfigRepository.js +13 -13
  4. package/dist/ChannelConfigRepository.js.map +1 -1
  5. package/dist/ChannelManager.d.ts +1 -1
  6. package/dist/ChannelManager.d.ts.map +1 -1
  7. package/dist/ChannelManager.js +9 -9
  8. package/dist/ChannelManager.js.map +1 -1
  9. package/dist/__tests__/ChannelConfigRepository.test.js +72 -72
  10. package/dist/__tests__/ChannelConfigRepository.test.js.map +1 -1
  11. package/dist/__tests__/ChannelManager.test.js +26 -26
  12. package/dist/__tests__/ChannelManager.test.js.map +1 -1
  13. package/dist/__tests__/adapters/slack/SlackAdapter.test.js +137 -137
  14. package/dist/__tests__/adapters/slack/SlackAdapter.test.js.map +1 -1
  15. package/dist/__tests__/adapters/slack/SlackMessageDelivery.test.js +36 -36
  16. package/dist/__tests__/adapters/slack/SlackMessageDelivery.test.js.map +1 -1
  17. package/dist/__tests__/adapters/slack/slackMarkdown.test.js +25 -25
  18. package/dist/__tests__/adapters/slack/slackMarkdown.test.js.map +1 -1
  19. package/dist/__tests__/adapters/slack/slackQuestion.test.js +41 -41
  20. package/dist/__tests__/adapters/slack/slackQuestion.test.js.map +1 -1
  21. package/dist/__tests__/adapters/telegram/TelegramAdapter.test.js +154 -154
  22. package/dist/__tests__/adapters/telegram/TelegramAdapter.test.js.map +1 -1
  23. package/dist/__tests__/adapters/telegram/telegramHtml.test.js +109 -109
  24. package/dist/__tests__/adapters/telegram/telegramHtml.test.js.map +1 -1
  25. package/dist/adapters/ChannelAdapter.d.ts +1 -1
  26. package/dist/adapters/ChannelAdapter.d.ts.map +1 -1
  27. package/dist/adapters/ChannelAdapter.js +1 -1
  28. package/dist/adapters/ChannelAdapter.js.map +1 -1
  29. package/dist/adapters/slack/SlackAdapter.d.ts +2 -2
  30. package/dist/adapters/slack/SlackAdapter.d.ts.map +1 -1
  31. package/dist/adapters/slack/SlackAdapter.js +17 -17
  32. package/dist/adapters/slack/SlackAdapter.js.map +1 -1
  33. package/dist/adapters/slack/SlackMessageDelivery.d.ts +1 -1
  34. package/dist/adapters/slack/SlackMessageDelivery.d.ts.map +1 -1
  35. package/dist/adapters/slack/SlackMessageDelivery.js +6 -6
  36. package/dist/adapters/slack/SlackMessageDelivery.js.map +1 -1
  37. package/dist/adapters/slack/slackMarkdown.d.ts.map +1 -1
  38. package/dist/adapters/slack/slackMarkdown.js +36 -36
  39. package/dist/adapters/slack/slackMarkdown.js.map +1 -1
  40. package/dist/adapters/slack/slackQuestion.d.ts +7 -7
  41. package/dist/adapters/slack/slackQuestion.d.ts.map +1 -1
  42. package/dist/adapters/slack/slackQuestion.js +13 -13
  43. package/dist/adapters/slack/slackQuestion.js.map +1 -1
  44. package/dist/adapters/telegram/TelegramAdapter.d.ts +2 -2
  45. package/dist/adapters/telegram/TelegramAdapter.d.ts.map +1 -1
  46. package/dist/adapters/telegram/TelegramAdapter.js +30 -27
  47. package/dist/adapters/telegram/TelegramAdapter.js.map +1 -1
  48. package/dist/adapters/telegram/TelegramMessageDelivery.d.ts.map +1 -1
  49. package/dist/adapters/telegram/TelegramMessageDelivery.js +2 -2
  50. package/dist/adapters/telegram/TelegramMessageDelivery.js.map +1 -1
  51. package/dist/adapters/telegram/telegramHtml.d.ts.map +1 -1
  52. package/dist/adapters/telegram/telegramHtml.js +16 -16
  53. package/dist/adapters/telegram/telegramHtml.js.map +1 -1
  54. package/dist/adapters/telegram/telegramKeyboard.d.ts +1 -1
  55. package/dist/adapters/telegram/telegramKeyboard.d.ts.map +1 -1
  56. package/dist/adapters/telegram/telegramKeyboard.js.map +1 -1
  57. package/dist/adapters/telegram/telegramMarkdown.d.ts.map +1 -1
  58. package/dist/adapters/telegram/telegramMarkdown.js +28 -28
  59. package/dist/adapters/telegram/telegramMarkdown.js.map +1 -1
  60. package/dist/index.d.ts +9 -9
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +5 -5
  63. package/dist/index.js.map +1 -1
  64. package/dist/types.d.ts +6 -6
  65. package/dist/types.d.ts.map +1 -1
  66. package/dist/types.js +1 -1
  67. package/dist/types.js.map +1 -1
  68. package/package.json +21 -22
  69. package/vitest.config.ts +16 -16
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/adapters/slack/slackQuestion.ts"],"sourcesContent":["import type { ChannelQuestion } from '../../types.js';\nimport { escapeSlackText } from './slackMarkdown.js';\n\ninterface SlackQuestionButton {\n type: 'button';\n action_id: 'ai_devkit_question';\n text: { type: 'plain_text'; text: string };\n value: string;\n}\n\ntype SlackQuestionMessage = Record<string, unknown> & {\n channel: string;\n text: string;\n blocks: [\n {\n type: 'section';\n text: { type: 'mrkdwn'; text: string };\n },\n {\n type: 'actions';\n elements: SlackQuestionButton[];\n },\n ];\n};\n\nexport function buildSlackQuestionMessage(chatId: string, question: ChannelQuestion): SlackQuestionMessage {\n const fallbackPrefix = question.header ? `${question.header}: ` : '';\n const fallback = escapeSlackText(`${fallbackPrefix}${question.question}`);\n const buttons = question.options.map((option): SlackQuestionButton => ({\n type: 'button',\n action_id: 'ai_devkit_question',\n text: { type: 'plain_text', text: option.label.slice(0, 75) },\n value: `${question.id}:${option.value}`.slice(0, 2000),\n }));\n\n if (question.allowSkip) {\n buttons.push({\n type: 'button',\n action_id: 'ai_devkit_question',\n text: { type: 'plain_text', text: 'Skip' },\n value: `${question.id}:skip`,\n });\n }\n\n return {\n channel: chatId,\n text: fallback,\n blocks: [\n {\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: `*${escapeSlackText(question.header ?? 'Question')}*\\n${escapeSlackText(question.question)}`,\n },\n },\n {\n type: 'actions',\n elements: buttons,\n },\n ],\n };\n}\n"],"names":["escapeSlackText","buildSlackQuestionMessage","chatId","question","fallbackPrefix","header","fallback","buttons","options","map","option","type","action_id","text","label","slice","value","id","allowSkip","push","channel","blocks","elements"],"mappings":"AACA,SAASA,eAAe,QAAQ,qBAAqB;AAwBrD,OAAO,SAASC,0BAA0BC,MAAc,EAAEC,QAAyB;IAC/E,MAAMC,iBAAiBD,SAASE,MAAM,GAAG,GAAGF,SAASE,MAAM,CAAC,EAAE,CAAC,GAAG;IAClE,MAAMC,WAAWN,gBAAgB,GAAGI,iBAAiBD,SAASA,QAAQ,EAAE;IACxE,MAAMI,UAAUJ,SAASK,OAAO,CAACC,GAAG,CAAC,CAACC,SAAiC,CAAA;YACnEC,MAAM;YACNC,WAAW;YACXC,MAAM;gBAAEF,MAAM;gBAAcE,MAAMH,OAAOI,KAAK,CAACC,KAAK,CAAC,GAAG;YAAI;YAC5DC,OAAO,GAAGb,SAASc,EAAE,CAAC,CAAC,EAAEP,OAAOM,KAAK,EAAE,CAACD,KAAK,CAAC,GAAG;QACrD,CAAA;IAEA,IAAIZ,SAASe,SAAS,EAAE;QACpBX,QAAQY,IAAI,CAAC;YACTR,MAAM;YACNC,WAAW;YACXC,MAAM;gBAAEF,MAAM;gBAAcE,MAAM;YAAO;YACzCG,OAAO,GAAGb,SAASc,EAAE,CAAC,KAAK,CAAC;QAChC;IACJ;IAEA,OAAO;QACHG,SAASlB;QACTW,MAAMP;QACNe,QAAQ;YACJ;gBACIV,MAAM;gBACNE,MAAM;oBACFF,MAAM;oBACNE,MAAM,CAAC,CAAC,EAAEb,gBAAgBG,SAASE,MAAM,IAAI,YAAY,GAAG,EAAEL,gBAAgBG,SAASA,QAAQ,GAAG;gBACtG;YACJ;YACA;gBACIQ,MAAM;gBACNW,UAAUf;YACd;SACH;IACL;AACJ"}
1
+ {"version":3,"sources":["../../../src/adapters/slack/slackQuestion.ts"],"sourcesContent":["import type { ChannelQuestion } from \"../../types.js\";\nimport { escapeSlackText } from \"./slackMarkdown.js\";\n\ninterface SlackQuestionButton {\n type: \"button\";\n action_id: \"ai_devkit_question\";\n text: { type: \"plain_text\"; text: string };\n value: string;\n}\n\ntype SlackQuestionMessage = Record<string, unknown> & {\n channel: string;\n text: string;\n blocks: [\n {\n type: \"section\";\n text: { type: \"mrkdwn\"; text: string };\n },\n {\n type: \"actions\";\n elements: SlackQuestionButton[];\n },\n ];\n};\n\nexport function buildSlackQuestionMessage(\n chatId: string,\n question: ChannelQuestion,\n): SlackQuestionMessage {\n const fallbackPrefix = question.header ? `${question.header}: ` : \"\";\n const fallback = escapeSlackText(`${fallbackPrefix}${question.question}`);\n const buttons = question.options.map((option): SlackQuestionButton => ({\n type: \"button\",\n action_id: \"ai_devkit_question\",\n text: { type: \"plain_text\", text: option.label.slice(0, 75) },\n value: `${question.id}:${option.value}`.slice(0, 2000),\n }));\n\n if (question.allowSkip) {\n buttons.push({\n type: \"button\",\n action_id: \"ai_devkit_question\",\n text: { type: \"plain_text\", text: \"Skip\" },\n value: `${question.id}:skip`,\n });\n }\n\n return {\n channel: chatId,\n text: fallback,\n blocks: [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*${escapeSlackText(question.header ?? \"Question\")}*\\n${escapeSlackText(question.question)}`,\n },\n },\n {\n type: \"actions\",\n elements: buttons,\n },\n ],\n };\n}\n"],"names":["escapeSlackText","buildSlackQuestionMessage","chatId","question","fallbackPrefix","header","fallback","buttons","options","map","option","type","action_id","text","label","slice","value","id","allowSkip","push","channel","blocks","elements"],"mappings":"AACA,SAASA,eAAe,QAAQ,qBAAqB;AAwBrD,OAAO,SAASC,0BACdC,MAAc,EACdC,QAAyB;IAEzB,MAAMC,iBAAiBD,SAASE,MAAM,GAAG,GAAGF,SAASE,MAAM,CAAC,EAAE,CAAC,GAAG;IAClE,MAAMC,WAAWN,gBAAgB,GAAGI,iBAAiBD,SAASA,QAAQ,EAAE;IACxE,MAAMI,UAAUJ,SAASK,OAAO,CAACC,GAAG,CAAC,CAACC,SAAiC,CAAA;YACrEC,MAAM;YACNC,WAAW;YACXC,MAAM;gBAAEF,MAAM;gBAAcE,MAAMH,OAAOI,KAAK,CAACC,KAAK,CAAC,GAAG;YAAI;YAC5DC,OAAO,GAAGb,SAASc,EAAE,CAAC,CAAC,EAAEP,OAAOM,KAAK,EAAE,CAACD,KAAK,CAAC,GAAG;QACnD,CAAA;IAEA,IAAIZ,SAASe,SAAS,EAAE;QACtBX,QAAQY,IAAI,CAAC;YACXR,MAAM;YACNC,WAAW;YACXC,MAAM;gBAAEF,MAAM;gBAAcE,MAAM;YAAO;YACzCG,OAAO,GAAGb,SAASc,EAAE,CAAC,KAAK,CAAC;QAC9B;IACF;IAEA,OAAO;QACLG,SAASlB;QACTW,MAAMP;QACNe,QAAQ;YACN;gBACEV,MAAM;gBACNE,MAAM;oBACJF,MAAM;oBACNE,MAAM,CAAC,CAAC,EAAEb,gBAAgBG,SAASE,MAAM,IAAI,YAAY,GAAG,EAAEL,gBAAgBG,SAASA,QAAQ,GAAG;gBACpG;YACF;YACA;gBACEQ,MAAM;gBACNW,UAAUf;YACZ;SACD;IACH;AACF"}
@@ -1,5 +1,5 @@
1
- import type { ChannelAdapter } from '../ChannelAdapter.js';
2
- import type { IncomingMessage, InlineKeyboard, CallbackHandler } from '../../types.js';
1
+ import type { ChannelAdapter } from "../ChannelAdapter.js";
2
+ import type { IncomingMessage, InlineKeyboard, CallbackHandler } from "../../types.js";
3
3
  export declare const TELEGRAM_CHANNEL_TYPE = "telegram";
4
4
  export interface TelegramAdapterOptions {
5
5
  botToken: string;
@@ -1 +1 @@
1
- {"version":3,"file":"TelegramAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/telegram/TelegramAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAoB,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEzG,eAAO,MAAM,qBAAqB,aAAa,CAAC;AAGhD,MAAM,WAAW,sBAAsB;IACnC,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,cAAc;IAClD,QAAQ,CAAC,IAAI,cAAyB;IAEtC,OAAO,CAAC,GAAG,CAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,cAAc,CAA0D;IAChF,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,sBAAsB;IAKrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4DtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIjE,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAI1C;;;;OAIG;IACG,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAQjG;;;OAGG;IACG,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3G;;;OAGG;IACG,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrE,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAGtC"}
1
+ {"version":3,"file":"TelegramAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/telegram/TelegramAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAEd,eAAe,EAChB,MAAM,gBAAgB,CAAC;AAExB,eAAO,MAAM,qBAAqB,aAAa,CAAC;AAGhD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,cAAc;IACpD,QAAQ,CAAC,IAAI,cAAyB;IAEtC,OAAO,CAAC,GAAG,CAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,cAAc,CAA0D;IAChF,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,sBAAsB;IAKrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwEtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIjE,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAI1C;;;;OAIG;IACG,kBAAkB,CACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC;IAQlB;;;OAGG;IACG,kBAAkB,CACtB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,cAAc,GAAG,IAAI,GAC9B,OAAO,CAAC,IAAI,CAAC;IAShB;;;OAGG;IACG,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrE,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAGpC"}
@@ -1,8 +1,8 @@
1
- import { Telegraf } from 'telegraf';
2
- import { TelegramMessageDelivery } from './TelegramMessageDelivery.js';
3
- import { toTelegrafKeyboard } from './telegramKeyboard.js';
4
- export const TELEGRAM_CHANNEL_TYPE = 'telegram';
5
- const TELEGRAM_PARSE_MODE = 'HTML';
1
+ import { Telegraf } from "telegraf";
2
+ import { TelegramMessageDelivery } from "./TelegramMessageDelivery.js";
3
+ import { toTelegrafKeyboard } from "./telegramKeyboard.js";
4
+ export const TELEGRAM_CHANNEL_TYPE = "telegram";
5
+ const TELEGRAM_PARSE_MODE = "HTML";
6
6
  /**
7
7
  * Telegram Bot API adapter using telegraf with long polling.
8
8
  */ export class TelegramAdapter {
@@ -17,7 +17,7 @@ const TELEGRAM_PARSE_MODE = 'HTML';
17
17
  this.delivery = new TelegramMessageDelivery(this.bot.telegram);
18
18
  }
19
19
  async start() {
20
- this.bot.on('text', async (ctx)=>{
20
+ this.bot.on("text", async (ctx)=>{
21
21
  if (!this.messageHandler) return;
22
22
  const msg = {
23
23
  channelType: TELEGRAM_CHANNEL_TYPE,
@@ -29,23 +29,25 @@ const TELEGRAM_PARSE_MODE = 'HTML';
29
29
  try {
30
30
  await this.messageHandler(msg);
31
31
  } catch (error) {
32
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
32
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
33
33
  await ctx.reply(`Error processing message: ${errorMessage}`);
34
34
  }
35
35
  });
36
- this.bot.on('callback_query', async (ctx)=>{
36
+ this.bot.on("callback_query", async (ctx)=>{
37
37
  if (!this.callbackHandler) {
38
38
  try {
39
39
  await ctx.answerCbQuery();
40
- } catch {}
40
+ } catch {
41
+ /* ignore */ }
41
42
  return;
42
43
  }
43
44
  const query = ctx.callbackQuery;
44
- const data = typeof query.data === 'string' ? query.data : '';
45
+ const data = typeof query.data === "string" ? query.data : "";
45
46
  if (!query.message) {
46
47
  try {
47
48
  await ctx.answerCbQuery();
48
- } catch {}
49
+ } catch {
50
+ /* ignore */ }
49
51
  return;
50
52
  }
51
53
  const cb = {
@@ -61,8 +63,9 @@ const TELEGRAM_PARSE_MODE = 'HTML';
61
63
  await this.callbackHandler(cb);
62
64
  } catch {
63
65
  try {
64
- await ctx.answerCbQuery('Error');
65
- } catch {}
66
+ await ctx.answerCbQuery("Error");
67
+ } catch {
68
+ /* ignore */ }
66
69
  }
67
70
  });
68
71
  await this.bot.launch();
@@ -73,10 +76,10 @@ const TELEGRAM_PARSE_MODE = 'HTML';
73
76
  await this.bot.stop();
74
77
  }
75
78
  /**
76
- * Input is treated as markdown and rendered as Telegram-compatible HTML.
77
- * Long messages are chunked as markdown source before rendering so each
78
- * Telegram HTML payload is independently valid.
79
- */ async sendMessage(chatId, text) {
79
+ * Input is treated as markdown and rendered as Telegram-compatible HTML.
80
+ * Long messages are chunked as markdown source before rendering so each
81
+ * Telegram HTML payload is independently valid.
82
+ */ async sendMessage(chatId, text) {
80
83
  await this.delivery.send(chatId, text);
81
84
  }
82
85
  onMessage(handler) {
@@ -86,10 +89,10 @@ const TELEGRAM_PARSE_MODE = 'HTML';
86
89
  this.callbackHandler = handler;
87
90
  }
88
91
  /**
89
- * Send a message with an inline keyboard. `html` is sent verbatim with
90
- * parse_mode=HTML - callers must pre-escape any user-controlled fields.
91
- * Returns the Telegram message_id of the sent message.
92
- */ async sendInlineKeyboard(chatId, html, keyboard) {
92
+ * Send a message with an inline keyboard. `html` is sent verbatim with
93
+ * parse_mode=HTML - callers must pre-escape any user-controlled fields.
94
+ * Returns the Telegram message_id of the sent message.
95
+ */ async sendInlineKeyboard(chatId, html, keyboard) {
93
96
  const result = await this.bot.telegram.sendMessage(chatId, html, {
94
97
  parse_mode: TELEGRAM_PARSE_MODE,
95
98
  reply_markup: {
@@ -99,17 +102,17 @@ const TELEGRAM_PARSE_MODE = 'HTML';
99
102
  return result.message_id;
100
103
  }
101
104
  /**
102
- * Replace the inline keyboard on an existing message. Pass `null` to remove
103
- * the keyboard entirely.
104
- */ async editInlineKeyboard(chatId, messageId, keyboard) {
105
+ * Replace the inline keyboard on an existing message. Pass `null` to remove
106
+ * the keyboard entirely.
107
+ */ async editInlineKeyboard(chatId, messageId, keyboard) {
105
108
  await this.bot.telegram.editMessageReplyMarkup(chatId, messageId, undefined, keyboard ? {
106
109
  inline_keyboard: toTelegrafKeyboard(keyboard)
107
110
  } : undefined);
108
111
  }
109
112
  /**
110
- * Acknowledge a callback_query. Without this Telegram leaves a spinner on
111
- * the tapped button. Pass `text` to show a transient toast.
112
- */ async answerCallback(callbackQueryId, text) {
113
+ * Acknowledge a callback_query. Without this Telegram leaves a spinner on
114
+ * the tapped button. Pass `text` to show a transient toast.
115
+ */ async answerCallback(callbackQueryId, text) {
113
116
  await this.bot.telegram.answerCbQuery(callbackQueryId, text);
114
117
  }
115
118
  async isHealthy() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/adapters/telegram/TelegramAdapter.ts"],"sourcesContent":["import { Telegraf } from 'telegraf';\nimport type { ChannelAdapter } from '../ChannelAdapter.js';\nimport { TelegramMessageDelivery } from './TelegramMessageDelivery.js';\nimport { toTelegrafKeyboard } from './telegramKeyboard.js';\nimport type { IncomingMessage, InlineKeyboard, IncomingCallback, CallbackHandler } from '../../types.js';\n\nexport const TELEGRAM_CHANNEL_TYPE = 'telegram';\nconst TELEGRAM_PARSE_MODE = 'HTML' as const;\n\nexport interface TelegramAdapterOptions {\n botToken: string;\n}\n\n/**\n * Telegram Bot API adapter using telegraf with long polling.\n */\nexport class TelegramAdapter implements ChannelAdapter {\n readonly type = TELEGRAM_CHANNEL_TYPE;\n\n private bot: Telegraf;\n private readonly delivery: TelegramMessageDelivery;\n private messageHandler: ((msg: IncomingMessage) => Promise<void>) | null = null;\n private callbackHandler: CallbackHandler | null = null;\n private running = false;\n\n constructor(options: TelegramAdapterOptions) {\n this.bot = new Telegraf(options.botToken);\n this.delivery = new TelegramMessageDelivery(this.bot.telegram);\n }\n\n async start(): Promise<void> {\n this.bot.on('text', async (ctx) => {\n if (!this.messageHandler) return;\n\n const msg: IncomingMessage = {\n channelType: TELEGRAM_CHANNEL_TYPE,\n chatId: String(ctx.message.chat.id),\n userId: String(ctx.message.from.id),\n text: ctx.message.text,\n timestamp: new Date(ctx.message.date * 1000),\n };\n\n try {\n await this.messageHandler(msg);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n await ctx.reply(`Error processing message: ${errorMessage}`);\n }\n });\n\n this.bot.on('callback_query', async (ctx) => {\n if (!this.callbackHandler) {\n try { await ctx.answerCbQuery(); } catch { /* ignore */ }\n return;\n }\n\n const query = ctx.callbackQuery as {\n id: string;\n data?: string;\n message?: { message_id: number; chat: { id: number | string } };\n from: { id: number | string };\n };\n\n const data = typeof query.data === 'string' ? query.data : '';\n if (!query.message) {\n try { await ctx.answerCbQuery(); } catch { /* ignore */ }\n return;\n }\n\n const cb: IncomingCallback = {\n channelType: TELEGRAM_CHANNEL_TYPE,\n chatId: String(query.message.chat.id),\n userId: String(query.from.id),\n messageId: query.message.message_id,\n callbackData: data,\n callbackQueryId: query.id,\n timestamp: new Date(),\n };\n\n try {\n await this.callbackHandler(cb);\n } catch {\n try { await ctx.answerCbQuery('Error'); } catch { /* ignore */ }\n }\n });\n\n await this.bot.launch();\n this.running = true;\n }\n\n async stop(): Promise<void> {\n this.running = false;\n await this.bot.stop();\n }\n\n /**\n * Input is treated as markdown and rendered as Telegram-compatible HTML.\n * Long messages are chunked as markdown source before rendering so each\n * Telegram HTML payload is independently valid.\n */\n async sendMessage(chatId: string, text: string): Promise<void> {\n await this.delivery.send(chatId, text);\n }\n\n onMessage(handler: (msg: IncomingMessage) => Promise<void>): void {\n this.messageHandler = handler;\n }\n\n onCallback(handler: CallbackHandler): void {\n this.callbackHandler = handler;\n }\n\n /**\n * Send a message with an inline keyboard. `html` is sent verbatim with\n * parse_mode=HTML - callers must pre-escape any user-controlled fields.\n * Returns the Telegram message_id of the sent message.\n */\n async sendInlineKeyboard(chatId: string, html: string, keyboard: InlineKeyboard): Promise<number> {\n const result = await this.bot.telegram.sendMessage(chatId, html, {\n parse_mode: TELEGRAM_PARSE_MODE,\n reply_markup: { inline_keyboard: toTelegrafKeyboard(keyboard) },\n }) as { message_id: number };\n return result.message_id;\n }\n\n /**\n * Replace the inline keyboard on an existing message. Pass `null` to remove\n * the keyboard entirely.\n */\n async editInlineKeyboard(chatId: string, messageId: number, keyboard: InlineKeyboard | null): Promise<void> {\n await this.bot.telegram.editMessageReplyMarkup(chatId, messageId, undefined, keyboard\n ? { inline_keyboard: toTelegrafKeyboard(keyboard) }\n : undefined);\n }\n\n /**\n * Acknowledge a callback_query. Without this Telegram leaves a spinner on\n * the tapped button. Pass `text` to show a transient toast.\n */\n async answerCallback(callbackQueryId: string, text?: string): Promise<void> {\n await this.bot.telegram.answerCbQuery(callbackQueryId, text);\n }\n\n async isHealthy(): Promise<boolean> {\n return this.running;\n }\n}\n"],"names":["Telegraf","TelegramMessageDelivery","toTelegrafKeyboard","TELEGRAM_CHANNEL_TYPE","TELEGRAM_PARSE_MODE","TelegramAdapter","type","bot","delivery","messageHandler","callbackHandler","running","options","botToken","telegram","start","on","ctx","msg","channelType","chatId","String","message","chat","id","userId","from","text","timestamp","Date","date","error","errorMessage","Error","reply","answerCbQuery","query","callbackQuery","data","cb","messageId","message_id","callbackData","callbackQueryId","launch","stop","sendMessage","send","onMessage","handler","onCallback","sendInlineKeyboard","html","keyboard","result","parse_mode","reply_markup","inline_keyboard","editInlineKeyboard","editMessageReplyMarkup","undefined","answerCallback","isHealthy"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/adapters/telegram/TelegramAdapter.ts"],"sourcesContent":["import { Telegraf } from \"telegraf\";\nimport type { ChannelAdapter } from \"../ChannelAdapter.js\";\nimport { TelegramMessageDelivery } from \"./TelegramMessageDelivery.js\";\nimport { toTelegrafKeyboard } from \"./telegramKeyboard.js\";\nimport type {\n IncomingMessage,\n InlineKeyboard,\n IncomingCallback,\n CallbackHandler,\n} from \"../../types.js\";\n\nexport const TELEGRAM_CHANNEL_TYPE = \"telegram\";\nconst TELEGRAM_PARSE_MODE = \"HTML\" as const;\n\nexport interface TelegramAdapterOptions {\n botToken: string;\n}\n\n/**\n * Telegram Bot API adapter using telegraf with long polling.\n */\nexport class TelegramAdapter implements ChannelAdapter {\n readonly type = TELEGRAM_CHANNEL_TYPE;\n\n private bot: Telegraf;\n private readonly delivery: TelegramMessageDelivery;\n private messageHandler: ((msg: IncomingMessage) => Promise<void>) | null = null;\n private callbackHandler: CallbackHandler | null = null;\n private running = false;\n\n constructor(options: TelegramAdapterOptions) {\n this.bot = new Telegraf(options.botToken);\n this.delivery = new TelegramMessageDelivery(this.bot.telegram);\n }\n\n async start(): Promise<void> {\n this.bot.on(\"text\", async (ctx) => {\n if (!this.messageHandler) return;\n\n const msg: IncomingMessage = {\n channelType: TELEGRAM_CHANNEL_TYPE,\n chatId: String(ctx.message.chat.id),\n userId: String(ctx.message.from.id),\n text: ctx.message.text,\n timestamp: new Date(ctx.message.date * 1000),\n };\n\n try {\n await this.messageHandler(msg);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\n await ctx.reply(`Error processing message: ${errorMessage}`);\n }\n });\n\n this.bot.on(\"callback_query\", async (ctx) => {\n if (!this.callbackHandler) {\n try {\n await ctx.answerCbQuery();\n } catch {\n /* ignore */\n }\n return;\n }\n\n const query = ctx.callbackQuery as {\n id: string;\n data?: string;\n message?: { message_id: number; chat: { id: number | string } };\n from: { id: number | string };\n };\n\n const data = typeof query.data === \"string\" ? query.data : \"\";\n if (!query.message) {\n try {\n await ctx.answerCbQuery();\n } catch {\n /* ignore */\n }\n return;\n }\n\n const cb: IncomingCallback = {\n channelType: TELEGRAM_CHANNEL_TYPE,\n chatId: String(query.message.chat.id),\n userId: String(query.from.id),\n messageId: query.message.message_id,\n callbackData: data,\n callbackQueryId: query.id,\n timestamp: new Date(),\n };\n\n try {\n await this.callbackHandler(cb);\n } catch {\n try {\n await ctx.answerCbQuery(\"Error\");\n } catch {\n /* ignore */\n }\n }\n });\n\n await this.bot.launch();\n this.running = true;\n }\n\n async stop(): Promise<void> {\n this.running = false;\n await this.bot.stop();\n }\n\n /**\n * Input is treated as markdown and rendered as Telegram-compatible HTML.\n * Long messages are chunked as markdown source before rendering so each\n * Telegram HTML payload is independently valid.\n */\n async sendMessage(chatId: string, text: string): Promise<void> {\n await this.delivery.send(chatId, text);\n }\n\n onMessage(handler: (msg: IncomingMessage) => Promise<void>): void {\n this.messageHandler = handler;\n }\n\n onCallback(handler: CallbackHandler): void {\n this.callbackHandler = handler;\n }\n\n /**\n * Send a message with an inline keyboard. `html` is sent verbatim with\n * parse_mode=HTML - callers must pre-escape any user-controlled fields.\n * Returns the Telegram message_id of the sent message.\n */\n async sendInlineKeyboard(\n chatId: string,\n html: string,\n keyboard: InlineKeyboard,\n ): Promise<number> {\n const result = (await this.bot.telegram.sendMessage(chatId, html, {\n parse_mode: TELEGRAM_PARSE_MODE,\n reply_markup: { inline_keyboard: toTelegrafKeyboard(keyboard) },\n })) as { message_id: number };\n return result.message_id;\n }\n\n /**\n * Replace the inline keyboard on an existing message. Pass `null` to remove\n * the keyboard entirely.\n */\n async editInlineKeyboard(\n chatId: string,\n messageId: number,\n keyboard: InlineKeyboard | null,\n ): Promise<void> {\n await this.bot.telegram.editMessageReplyMarkup(\n chatId,\n messageId,\n undefined,\n keyboard ? { inline_keyboard: toTelegrafKeyboard(keyboard) } : undefined,\n );\n }\n\n /**\n * Acknowledge a callback_query. Without this Telegram leaves a spinner on\n * the tapped button. Pass `text` to show a transient toast.\n */\n async answerCallback(callbackQueryId: string, text?: string): Promise<void> {\n await this.bot.telegram.answerCbQuery(callbackQueryId, text);\n }\n\n async isHealthy(): Promise<boolean> {\n return this.running;\n }\n}\n"],"names":["Telegraf","TelegramMessageDelivery","toTelegrafKeyboard","TELEGRAM_CHANNEL_TYPE","TELEGRAM_PARSE_MODE","TelegramAdapter","type","bot","delivery","messageHandler","callbackHandler","running","options","botToken","telegram","start","on","ctx","msg","channelType","chatId","String","message","chat","id","userId","from","text","timestamp","Date","date","error","errorMessage","Error","reply","answerCbQuery","query","callbackQuery","data","cb","messageId","message_id","callbackData","callbackQueryId","launch","stop","sendMessage","send","onMessage","handler","onCallback","sendInlineKeyboard","html","keyboard","result","parse_mode","reply_markup","inline_keyboard","editInlineKeyboard","editMessageReplyMarkup","undefined","answerCallback","isHealthy"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,WAAW;AAEpC,SAASC,uBAAuB,QAAQ,+BAA+B;AACvE,SAASC,kBAAkB,QAAQ,wBAAwB;AAQ3D,OAAO,MAAMC,wBAAwB,WAAW;AAChD,MAAMC,sBAAsB;AAM5B;;CAEC,GACD,OAAO,MAAMC;IACFC,OAAOH,sBAAsB;IAE9BI,IAAc;IACLC,SAAkC;IAC3CC,iBAAmE,KAAK;IACxEC,kBAA0C,KAAK;IAC/CC,UAAU,MAAM;IAExB,YAAYC,OAA+B,CAAE;QAC3C,IAAI,CAACL,GAAG,GAAG,IAAIP,SAASY,QAAQC,QAAQ;QACxC,IAAI,CAACL,QAAQ,GAAG,IAAIP,wBAAwB,IAAI,CAACM,GAAG,CAACO,QAAQ;IAC/D;IAEA,MAAMC,QAAuB;QAC3B,IAAI,CAACR,GAAG,CAACS,EAAE,CAAC,QAAQ,OAAOC;YACzB,IAAI,CAAC,IAAI,CAACR,cAAc,EAAE;YAE1B,MAAMS,MAAuB;gBAC3BC,aAAahB;gBACbiB,QAAQC,OAAOJ,IAAIK,OAAO,CAACC,IAAI,CAACC,EAAE;gBAClCC,QAAQJ,OAAOJ,IAAIK,OAAO,CAACI,IAAI,CAACF,EAAE;gBAClCG,MAAMV,IAAIK,OAAO,CAACK,IAAI;gBACtBC,WAAW,IAAIC,KAAKZ,IAAIK,OAAO,CAACQ,IAAI,GAAG;YACzC;YAEA,IAAI;gBACF,MAAM,IAAI,CAACrB,cAAc,CAACS;YAC5B,EAAE,OAAOa,OAAO;gBACd,MAAMC,eAAeD,iBAAiBE,QAAQF,MAAMT,OAAO,GAAG;gBAC9D,MAAML,IAAIiB,KAAK,CAAC,CAAC,0BAA0B,EAAEF,cAAc;YAC7D;QACF;QAEA,IAAI,CAACzB,GAAG,CAACS,EAAE,CAAC,kBAAkB,OAAOC;YACnC,IAAI,CAAC,IAAI,CAACP,eAAe,EAAE;gBACzB,IAAI;oBACF,MAAMO,IAAIkB,aAAa;gBACzB,EAAE,OAAM;gBACN,UAAU,GACZ;gBACA;YACF;YAEA,MAAMC,QAAQnB,IAAIoB,aAAa;YAO/B,MAAMC,OAAO,OAAOF,MAAME,IAAI,KAAK,WAAWF,MAAME,IAAI,GAAG;YAC3D,IAAI,CAACF,MAAMd,OAAO,EAAE;gBAClB,IAAI;oBACF,MAAML,IAAIkB,aAAa;gBACzB,EAAE,OAAM;gBACN,UAAU,GACZ;gBACA;YACF;YAEA,MAAMI,KAAuB;gBAC3BpB,aAAahB;gBACbiB,QAAQC,OAAOe,MAAMd,OAAO,CAACC,IAAI,CAACC,EAAE;gBACpCC,QAAQJ,OAAOe,MAAMV,IAAI,CAACF,EAAE;gBAC5BgB,WAAWJ,MAAMd,OAAO,CAACmB,UAAU;gBACnCC,cAAcJ;gBACdK,iBAAiBP,MAAMZ,EAAE;gBACzBI,WAAW,IAAIC;YACjB;YAEA,IAAI;gBACF,MAAM,IAAI,CAACnB,eAAe,CAAC6B;YAC7B,EAAE,OAAM;gBACN,IAAI;oBACF,MAAMtB,IAAIkB,aAAa,CAAC;gBAC1B,EAAE,OAAM;gBACN,UAAU,GACZ;YACF;QACF;QAEA,MAAM,IAAI,CAAC5B,GAAG,CAACqC,MAAM;QACrB,IAAI,CAACjC,OAAO,GAAG;IACjB;IAEA,MAAMkC,OAAsB;QAC1B,IAAI,CAAClC,OAAO,GAAG;QACf,MAAM,IAAI,CAACJ,GAAG,CAACsC,IAAI;IACrB;IAEA;;;;GAIC,GACD,MAAMC,YAAY1B,MAAc,EAAEO,IAAY,EAAiB;QAC7D,MAAM,IAAI,CAACnB,QAAQ,CAACuC,IAAI,CAAC3B,QAAQO;IACnC;IAEAqB,UAAUC,OAAgD,EAAQ;QAChE,IAAI,CAACxC,cAAc,GAAGwC;IACxB;IAEAC,WAAWD,OAAwB,EAAQ;QACzC,IAAI,CAACvC,eAAe,GAAGuC;IACzB;IAEA;;;;GAIC,GACD,MAAME,mBACJ/B,MAAc,EACdgC,IAAY,EACZC,QAAwB,EACP;QACjB,MAAMC,SAAU,MAAM,IAAI,CAAC/C,GAAG,CAACO,QAAQ,CAACgC,WAAW,CAAC1B,QAAQgC,MAAM;YAChEG,YAAYnD;YACZoD,cAAc;gBAAEC,iBAAiBvD,mBAAmBmD;YAAU;QAChE;QACA,OAAOC,OAAOb,UAAU;IAC1B;IAEA;;;GAGC,GACD,MAAMiB,mBACJtC,MAAc,EACdoB,SAAiB,EACjBa,QAA+B,EAChB;QACf,MAAM,IAAI,CAAC9C,GAAG,CAACO,QAAQ,CAAC6C,sBAAsB,CAC5CvC,QACAoB,WACAoB,WACAP,WAAW;YAAEI,iBAAiBvD,mBAAmBmD;QAAU,IAAIO;IAEnE;IAEA;;;GAGC,GACD,MAAMC,eAAelB,eAAuB,EAAEhB,IAAa,EAAiB;QAC1E,MAAM,IAAI,CAACpB,GAAG,CAACO,QAAQ,CAACqB,aAAa,CAACQ,iBAAiBhB;IACzD;IAEA,MAAMmC,YAA8B;QAClC,OAAO,IAAI,CAACnD,OAAO;IACrB;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"TelegramMessageDelivery.d.ts","sourceRoot":"","sources":["../../../src/adapters/telegram/TelegramMessageDelivery.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAGhD,UAAU,cAAc;IACpB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAChG;AAED,qBAAa,uBAAuB;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAE7C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA2B1D"}
1
+ {"version":3,"file":"TelegramMessageDelivery.d.ts","sourceRoot":"","sources":["../../../src/adapters/telegram/TelegramMessageDelivery.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAGhD,UAAU,cAAc;IACtB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9F;AAED,qBAAa,uBAAuB;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAE7C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA2BxD"}
@@ -1,6 +1,6 @@
1
- import { chunkMarkdownForTelegram, chunkMessage, htmlToPlainText, isParseEntitiesError } from './telegramMarkdown.js';
1
+ import { chunkMarkdownForTelegram, chunkMessage, htmlToPlainText, isParseEntitiesError } from "./telegramMarkdown.js";
2
2
  export const TELEGRAM_MAX_MESSAGE_LENGTH = 4096;
3
- const TELEGRAM_PARSE_MODE = 'HTML';
3
+ const TELEGRAM_PARSE_MODE = "HTML";
4
4
  export class TelegramMessageDelivery {
5
5
  sender;
6
6
  constructor(sender){
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/adapters/telegram/TelegramMessageDelivery.ts"],"sourcesContent":["import {\n chunkMarkdownForTelegram,\n chunkMessage,\n htmlToPlainText,\n isParseEntitiesError,\n type TelegramMessageChunk,\n} from './telegramMarkdown.js';\n\nexport const TELEGRAM_MAX_MESSAGE_LENGTH = 4096;\nconst TELEGRAM_PARSE_MODE = 'HTML' as const;\n\ninterface TelegramSender {\n sendMessage(chatId: string, text: string, extra?: Record<string, unknown>): Promise<unknown>;\n}\n\nexport class TelegramMessageDelivery {\n constructor(private readonly sender: TelegramSender) {}\n\n async send(chatId: string, text: string): Promise<void> {\n let chunks: TelegramMessageChunk[];\n try {\n chunks = chunkMarkdownForTelegram(text, TELEGRAM_MAX_MESSAGE_LENGTH);\n } catch {\n for (const chunk of chunkMessage(text, TELEGRAM_MAX_MESSAGE_LENGTH)) {\n await this.sender.sendMessage(chatId, chunk);\n }\n return;\n }\n\n for (const chunk of chunks) {\n if (!chunk.html) {\n await this.sender.sendMessage(chatId, chunk.text);\n continue;\n }\n\n try {\n await this.sender.sendMessage(chatId, chunk.text, { parse_mode: TELEGRAM_PARSE_MODE });\n } catch (error) {\n if (!isParseEntitiesError(error)) throw error;\n // Telegram rejected the rendered HTML - fall back to plain text\n // so the user still gets the content (just unformatted).\n await this.sender.sendMessage(chatId, htmlToPlainText(chunk.text));\n }\n }\n }\n}\n"],"names":["chunkMarkdownForTelegram","chunkMessage","htmlToPlainText","isParseEntitiesError","TELEGRAM_MAX_MESSAGE_LENGTH","TELEGRAM_PARSE_MODE","TelegramMessageDelivery","sender","send","chatId","text","chunks","chunk","sendMessage","html","parse_mode","error"],"mappings":"AAAA,SACIA,wBAAwB,EACxBC,YAAY,EACZC,eAAe,EACfC,oBAAoB,QAEjB,wBAAwB;AAE/B,OAAO,MAAMC,8BAA8B,KAAK;AAChD,MAAMC,sBAAsB;AAM5B,OAAO,MAAMC;;IACT,YAAY,AAAiBC,MAAsB,CAAE;aAAxBA,SAAAA;IAAyB;IAEtD,MAAMC,KAAKC,MAAc,EAAEC,IAAY,EAAiB;QACpD,IAAIC;QACJ,IAAI;YACAA,SAASX,yBAAyBU,MAAMN;QAC5C,EAAE,OAAM;YACJ,KAAK,MAAMQ,SAASX,aAAaS,MAAMN,6BAA8B;gBACjE,MAAM,IAAI,CAACG,MAAM,CAACM,WAAW,CAACJ,QAAQG;YAC1C;YACA;QACJ;QAEA,KAAK,MAAMA,SAASD,OAAQ;YACxB,IAAI,CAACC,MAAME,IAAI,EAAE;gBACb,MAAM,IAAI,CAACP,MAAM,CAACM,WAAW,CAACJ,QAAQG,MAAMF,IAAI;gBAChD;YACJ;YAEA,IAAI;gBACA,MAAM,IAAI,CAACH,MAAM,CAACM,WAAW,CAACJ,QAAQG,MAAMF,IAAI,EAAE;oBAAEK,YAAYV;gBAAoB;YACxF,EAAE,OAAOW,OAAO;gBACZ,IAAI,CAACb,qBAAqBa,QAAQ,MAAMA;gBACxC,gEAAgE;gBAChE,yDAAyD;gBACzD,MAAM,IAAI,CAACT,MAAM,CAACM,WAAW,CAACJ,QAAQP,gBAAgBU,MAAMF,IAAI;YACpE;QACJ;IACJ;AACJ"}
1
+ {"version":3,"sources":["../../../src/adapters/telegram/TelegramMessageDelivery.ts"],"sourcesContent":["import {\n chunkMarkdownForTelegram,\n chunkMessage,\n htmlToPlainText,\n isParseEntitiesError,\n type TelegramMessageChunk,\n} from \"./telegramMarkdown.js\";\n\nexport const TELEGRAM_MAX_MESSAGE_LENGTH = 4096;\nconst TELEGRAM_PARSE_MODE = \"HTML\" as const;\n\ninterface TelegramSender {\n sendMessage(chatId: string, text: string, extra?: Record<string, unknown>): Promise<unknown>;\n}\n\nexport class TelegramMessageDelivery {\n constructor(private readonly sender: TelegramSender) {}\n\n async send(chatId: string, text: string): Promise<void> {\n let chunks: TelegramMessageChunk[];\n try {\n chunks = chunkMarkdownForTelegram(text, TELEGRAM_MAX_MESSAGE_LENGTH);\n } catch {\n for (const chunk of chunkMessage(text, TELEGRAM_MAX_MESSAGE_LENGTH)) {\n await this.sender.sendMessage(chatId, chunk);\n }\n return;\n }\n\n for (const chunk of chunks) {\n if (!chunk.html) {\n await this.sender.sendMessage(chatId, chunk.text);\n continue;\n }\n\n try {\n await this.sender.sendMessage(chatId, chunk.text, { parse_mode: TELEGRAM_PARSE_MODE });\n } catch (error) {\n if (!isParseEntitiesError(error)) throw error;\n // Telegram rejected the rendered HTML - fall back to plain text\n // so the user still gets the content (just unformatted).\n await this.sender.sendMessage(chatId, htmlToPlainText(chunk.text));\n }\n }\n }\n}\n"],"names":["chunkMarkdownForTelegram","chunkMessage","htmlToPlainText","isParseEntitiesError","TELEGRAM_MAX_MESSAGE_LENGTH","TELEGRAM_PARSE_MODE","TelegramMessageDelivery","sender","send","chatId","text","chunks","chunk","sendMessage","html","parse_mode","error"],"mappings":"AAAA,SACEA,wBAAwB,EACxBC,YAAY,EACZC,eAAe,EACfC,oBAAoB,QAEf,wBAAwB;AAE/B,OAAO,MAAMC,8BAA8B,KAAK;AAChD,MAAMC,sBAAsB;AAM5B,OAAO,MAAMC;;IACX,YAAY,AAAiBC,MAAsB,CAAE;aAAxBA,SAAAA;IAAyB;IAEtD,MAAMC,KAAKC,MAAc,EAAEC,IAAY,EAAiB;QACtD,IAAIC;QACJ,IAAI;YACFA,SAASX,yBAAyBU,MAAMN;QAC1C,EAAE,OAAM;YACN,KAAK,MAAMQ,SAASX,aAAaS,MAAMN,6BAA8B;gBACnE,MAAM,IAAI,CAACG,MAAM,CAACM,WAAW,CAACJ,QAAQG;YACxC;YACA;QACF;QAEA,KAAK,MAAMA,SAASD,OAAQ;YAC1B,IAAI,CAACC,MAAME,IAAI,EAAE;gBACf,MAAM,IAAI,CAACP,MAAM,CAACM,WAAW,CAACJ,QAAQG,MAAMF,IAAI;gBAChD;YACF;YAEA,IAAI;gBACF,MAAM,IAAI,CAACH,MAAM,CAACM,WAAW,CAACJ,QAAQG,MAAMF,IAAI,EAAE;oBAAEK,YAAYV;gBAAoB;YACtF,EAAE,OAAOW,OAAO;gBACd,IAAI,CAACb,qBAAqBa,QAAQ,MAAMA;gBACxC,gEAAgE;gBAChE,yDAAyD;gBACzD,MAAM,IAAI,CAACT,MAAM,CAACM,WAAW,CAACJ,QAAQP,gBAAgBU,MAAMF,IAAI;YAClE;QACF;IACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"telegramHtml.d.ts","sourceRoot":"","sources":["../../../src/adapters/telegram/telegramHtml.ts"],"names":[],"mappings":"AAyFA;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/D"}
1
+ {"version":3,"file":"telegramHtml.d.ts","sourceRoot":"","sources":["../../../src/adapters/telegram/telegramHtml.ts"],"names":[],"mappings":"AAuFA;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/D"}
@@ -1,6 +1,6 @@
1
- import { Marked } from 'marked';
2
- const escapeHtml = (s)=>s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
3
- const escapeUrl = (s)=>s.replace(/&/g, '&amp;').replace(/"/g, '&quot;');
1
+ import { Marked } from "marked";
2
+ const escapeHtml = (s)=>s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
3
+ const escapeUrl = (s)=>s.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
4
4
  const renderer = {
5
5
  heading ({ tokens }) {
6
6
  return `<b>${this.parser.parseInline(tokens)}</b>\n\n`;
@@ -21,7 +21,7 @@ const renderer = {
21
21
  return `<code>${escapeHtml(text)}</code>`;
22
22
  },
23
23
  code ({ text, lang }) {
24
- const langAttr = lang ? ` class="language-${escapeHtml(lang.split(/\s/)[0])}"` : '';
24
+ const langAttr = lang ? ` class="language-${escapeHtml(lang.split(/\s/)[0])}"` : "";
25
25
  return `<pre><code${langAttr}>${escapeHtml(text)}</code></pre>\n\n`;
26
26
  },
27
27
  link ({ href, tokens }) {
@@ -32,15 +32,15 @@ const renderer = {
32
32
  return `<a href="${escapeUrl(href)}">${escapeHtml(label)}</a>`;
33
33
  },
34
34
  list ({ items, ordered, start }) {
35
- const startNum = typeof start === 'number' ? start : 1;
35
+ const startNum = typeof start === "number" ? start : 1;
36
36
  const lines = items.map((item, i)=>{
37
- const marker = ordered ? `${startNum + i}.` : '•';
38
- const inner = item.tokens.map((token)=>token.type === 'text' ? this.parser.parseInline(token.tokens) : this.parser.parse([
37
+ const marker = ordered ? `${startNum + i}.` : "•";
38
+ const inner = item.tokens.map((token)=>token.type === "text" ? this.parser.parseInline(token.tokens) : this.parser.parse([
39
39
  token
40
- ])).join('').trimEnd();
40
+ ])).join("").trimEnd();
41
41
  return `${marker} ${inner}`;
42
42
  });
43
- return `${lines.join('\n')}\n\n`;
43
+ return `${lines.join("\n")}\n\n`;
44
44
  },
45
45
  blockquote ({ tokens }) {
46
46
  return `<blockquote>${this.parser.parse(tokens).trimEnd()}</blockquote>\n\n`;
@@ -48,23 +48,23 @@ const renderer = {
48
48
  table ({ header, rows }) {
49
49
  const headerCells = header.map((c)=>c.text);
50
50
  const bodyRows = rows.map((row)=>row.map((c)=>c.text));
51
- const widths = headerCells.map((h, i)=>Math.max(h.length, ...bodyRows.map((row)=>(row[i] ?? '').length)));
52
- const pad = (cells)=>cells.map((c, i)=>c.padEnd(widths[i] ?? 0)).join(' | ');
51
+ const widths = headerCells.map((h, i)=>Math.max(h.length, ...bodyRows.map((row)=>(row[i] ?? "").length)));
52
+ const pad = (cells)=>cells.map((c, i)=>c.padEnd(widths[i] ?? 0)).join(" | ");
53
53
  const lines = [
54
54
  pad(headerCells),
55
- widths.map((w)=>'-'.repeat(w)).join('-+-'),
55
+ widths.map((w)=>"-".repeat(w)).join("-+-"),
56
56
  ...bodyRows.map(pad)
57
57
  ];
58
- return `<pre>${escapeHtml(lines.join('\n'))}</pre>\n\n`;
58
+ return `<pre>${escapeHtml(lines.join("\n"))}</pre>\n\n`;
59
59
  },
60
60
  hr () {
61
- return '———\n\n';
61
+ return "———\n\n";
62
62
  },
63
63
  br () {
64
- return '\n';
64
+ return "\n";
65
65
  },
66
66
  html ({ block, text }) {
67
- return block ? '' : escapeHtml(text);
67
+ return block ? "" : escapeHtml(text);
68
68
  },
69
69
  text (token) {
70
70
  return escapeHtml(token.text);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/adapters/telegram/telegramHtml.ts"],"sourcesContent":["import { Marked, type RendererObject, type Tokens } from 'marked';\n\nconst escapeHtml = (s: string): string =>\n s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\nconst escapeUrl = (s: string): string =>\n s.replace(/&/g, '&amp;').replace(/\"/g, '&quot;');\n\nconst renderer: RendererObject = {\n heading({ tokens }: Tokens.Heading): string {\n return `<b>${this.parser.parseInline(tokens)}</b>\\n\\n`;\n },\n paragraph({ tokens }: Tokens.Paragraph): string {\n return `${this.parser.parseInline(tokens)}\\n\\n`;\n },\n strong({ tokens }: Tokens.Strong): string {\n return `<b>${this.parser.parseInline(tokens)}</b>`;\n },\n em({ tokens }: Tokens.Em): string {\n return `<i>${this.parser.parseInline(tokens)}</i>`;\n },\n del({ tokens }: Tokens.Del): string {\n return `<s>${this.parser.parseInline(tokens)}</s>`;\n },\n codespan({ text }: Tokens.Codespan): string {\n return `<code>${escapeHtml(text)}</code>`;\n },\n code({ text, lang }: Tokens.Code): string {\n const langAttr = lang ? ` class=\"language-${escapeHtml(lang.split(/\\s/)[0])}\"` : '';\n return `<pre><code${langAttr}>${escapeHtml(text)}</code></pre>\\n\\n`;\n },\n link({ href, tokens }: Tokens.Link): string {\n return `<a href=\"${escapeUrl(href)}\">${this.parser.parseInline(tokens)}</a>`;\n },\n image({ href, text }: Tokens.Image): string {\n const label = text || href;\n return `<a href=\"${escapeUrl(href)}\">${escapeHtml(label)}</a>`;\n },\n list({ items, ordered, start }: Tokens.List): string {\n const startNum = typeof start === 'number' ? start : 1;\n const lines = items.map((item, i) => {\n const marker = ordered ? `${startNum + i}.` : '•';\n const inner = item.tokens\n .map((token) =>\n token.type === 'text'\n ? this.parser.parseInline(token.tokens!)\n : this.parser.parse([token])\n )\n .join('')\n .trimEnd();\n return `${marker} ${inner}`;\n });\n return `${lines.join('\\n')}\\n\\n`;\n },\n blockquote({ tokens }: Tokens.Blockquote): string {\n return `<blockquote>${this.parser.parse(tokens).trimEnd()}</blockquote>\\n\\n`;\n },\n table({ header, rows }: Tokens.Table): string {\n const headerCells = header.map((c) => c.text);\n const bodyRows = rows.map((row) => row.map((c) => c.text));\n const widths = headerCells.map((h, i) =>\n Math.max(h.length, ...bodyRows.map((row) => (row[i] ?? '').length))\n );\n const pad = (cells: string[]) =>\n cells.map((c, i) => c.padEnd(widths[i] ?? 0)).join(' | ');\n\n const lines = [\n pad(headerCells),\n widths.map((w) => '-'.repeat(w)).join('-+-'),\n ...bodyRows.map(pad),\n ];\n return `<pre>${escapeHtml(lines.join('\\n'))}</pre>\\n\\n`;\n },\n hr(): string {\n return '———\\n\\n';\n },\n br(): string {\n return '\\n';\n },\n html({ block, text }: Tokens.HTML | Tokens.Tag): string {\n return block ? '' : escapeHtml(text);\n },\n text(token: Tokens.Text | Tokens.Escape): string {\n return escapeHtml(token.text);\n },\n};\n\nconst marked = new Marked({ renderer });\n\n/**\n * Convert markdown to Telegram-compatible HTML (uses only the tag subset\n * Telegram's Bot API accepts for parse_mode: 'HTML').\n */\nexport function markdownToTelegramHtml(markdown: string): string {\n return (marked.parse(markdown, { async: false }) as string).trimEnd();\n}\n"],"names":["Marked","escapeHtml","s","replace","escapeUrl","renderer","heading","tokens","parser","parseInline","paragraph","strong","em","del","codespan","text","code","lang","langAttr","split","link","href","image","label","list","items","ordered","start","startNum","lines","map","item","i","marker","inner","token","type","parse","join","trimEnd","blockquote","table","header","rows","headerCells","c","bodyRows","row","widths","h","Math","max","length","pad","cells","padEnd","w","repeat","hr","br","html","block","marked","markdownToTelegramHtml","markdown","async"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/adapters/telegram/telegramHtml.ts"],"sourcesContent":["import { Marked, type RendererObject, type Tokens } from \"marked\";\n\nconst escapeHtml = (s: string): string =>\n s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n\nconst escapeUrl = (s: string): string => s.replace(/&/g, \"&amp;\").replace(/\"/g, \"&quot;\");\n\nconst renderer: RendererObject = {\n heading({ tokens }: Tokens.Heading): string {\n return `<b>${this.parser.parseInline(tokens)}</b>\\n\\n`;\n },\n paragraph({ tokens }: Tokens.Paragraph): string {\n return `${this.parser.parseInline(tokens)}\\n\\n`;\n },\n strong({ tokens }: Tokens.Strong): string {\n return `<b>${this.parser.parseInline(tokens)}</b>`;\n },\n em({ tokens }: Tokens.Em): string {\n return `<i>${this.parser.parseInline(tokens)}</i>`;\n },\n del({ tokens }: Tokens.Del): string {\n return `<s>${this.parser.parseInline(tokens)}</s>`;\n },\n codespan({ text }: Tokens.Codespan): string {\n return `<code>${escapeHtml(text)}</code>`;\n },\n code({ text, lang }: Tokens.Code): string {\n const langAttr = lang ? ` class=\"language-${escapeHtml(lang.split(/\\s/)[0])}\"` : \"\";\n return `<pre><code${langAttr}>${escapeHtml(text)}</code></pre>\\n\\n`;\n },\n link({ href, tokens }: Tokens.Link): string {\n return `<a href=\"${escapeUrl(href)}\">${this.parser.parseInline(tokens)}</a>`;\n },\n image({ href, text }: Tokens.Image): string {\n const label = text || href;\n return `<a href=\"${escapeUrl(href)}\">${escapeHtml(label)}</a>`;\n },\n list({ items, ordered, start }: Tokens.List): string {\n const startNum = typeof start === \"number\" ? start : 1;\n const lines = items.map((item, i) => {\n const marker = ordered ? `${startNum + i}.` : \"•\";\n const inner = item.tokens\n .map((token) =>\n token.type === \"text\"\n ? this.parser.parseInline(token.tokens!)\n : this.parser.parse([token]),\n )\n .join(\"\")\n .trimEnd();\n return `${marker} ${inner}`;\n });\n return `${lines.join(\"\\n\")}\\n\\n`;\n },\n blockquote({ tokens }: Tokens.Blockquote): string {\n return `<blockquote>${this.parser.parse(tokens).trimEnd()}</blockquote>\\n\\n`;\n },\n table({ header, rows }: Tokens.Table): string {\n const headerCells = header.map((c) => c.text);\n const bodyRows = rows.map((row) => row.map((c) => c.text));\n const widths = headerCells.map((h, i) =>\n Math.max(h.length, ...bodyRows.map((row) => (row[i] ?? \"\").length)),\n );\n const pad = (cells: string[]) => cells.map((c, i) => c.padEnd(widths[i] ?? 0)).join(\" | \");\n\n const lines = [\n pad(headerCells),\n widths.map((w) => \"-\".repeat(w)).join(\"-+-\"),\n ...bodyRows.map(pad),\n ];\n return `<pre>${escapeHtml(lines.join(\"\\n\"))}</pre>\\n\\n`;\n },\n hr(): string {\n return \"———\\n\\n\";\n },\n br(): string {\n return \"\\n\";\n },\n html({ block, text }: Tokens.HTML | Tokens.Tag): string {\n return block ? \"\" : escapeHtml(text);\n },\n text(token: Tokens.Text | Tokens.Escape): string {\n return escapeHtml(token.text);\n },\n};\n\nconst marked = new Marked({ renderer });\n\n/**\n * Convert markdown to Telegram-compatible HTML (uses only the tag subset\n * Telegram's Bot API accepts for parse_mode: 'HTML').\n */\nexport function markdownToTelegramHtml(markdown: string): string {\n return (marked.parse(markdown, { async: false }) as string).trimEnd();\n}\n"],"names":["Marked","escapeHtml","s","replace","escapeUrl","renderer","heading","tokens","parser","parseInline","paragraph","strong","em","del","codespan","text","code","lang","langAttr","split","link","href","image","label","list","items","ordered","start","startNum","lines","map","item","i","marker","inner","token","type","parse","join","trimEnd","blockquote","table","header","rows","headerCells","c","bodyRows","row","widths","h","Math","max","length","pad","cells","padEnd","w","repeat","hr","br","html","block","marked","markdownToTelegramHtml","markdown","async"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { InlineKeyboard } from '../../types.js';
1
+ import type { InlineKeyboard } from "../../types.js";
2
2
  export interface TelegrafInlineKeyboardButton {
3
3
  text: string;
4
4
  callback_data: string;
@@ -1 +1 @@
1
- {"version":3,"file":"telegramKeyboard.d.ts","sourceRoot":"","sources":["../../../src/adapters/telegram/telegramKeyboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,WAAW,4BAA4B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,4BAA4B,EAAE,EAAE,CAE7F"}
1
+ {"version":3,"file":"telegramKeyboard.d.ts","sourceRoot":"","sources":["../../../src/adapters/telegram/telegramKeyboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,4BAA4B,EAAE,EAAE,CAI7F"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/adapters/telegram/telegramKeyboard.ts"],"sourcesContent":["import type { InlineKeyboard } from '../../types.js';\n\nexport interface TelegrafInlineKeyboardButton {\n text: string;\n callback_data: string;\n}\n\nexport function toTelegrafKeyboard(keyboard: InlineKeyboard): TelegrafInlineKeyboardButton[][] {\n return keyboard.map((row) => row.map((btn) => ({ text: btn.text, callback_data: btn.callbackData })));\n}\n"],"names":["toTelegrafKeyboard","keyboard","map","row","btn","text","callback_data","callbackData"],"mappings":"AAOA,OAAO,SAASA,mBAAmBC,QAAwB;IACvD,OAAOA,SAASC,GAAG,CAAC,CAACC,MAAQA,IAAID,GAAG,CAAC,CAACE,MAAS,CAAA;gBAAEC,MAAMD,IAAIC,IAAI;gBAAEC,eAAeF,IAAIG,YAAY;YAAC,CAAA;AACrG"}
1
+ {"version":3,"sources":["../../../src/adapters/telegram/telegramKeyboard.ts"],"sourcesContent":["import type { InlineKeyboard } from \"../../types.js\";\n\nexport interface TelegrafInlineKeyboardButton {\n text: string;\n callback_data: string;\n}\n\nexport function toTelegrafKeyboard(keyboard: InlineKeyboard): TelegrafInlineKeyboardButton[][] {\n return keyboard.map((row) =>\n row.map((btn) => ({ text: btn.text, callback_data: btn.callbackData })),\n );\n}\n"],"names":["toTelegrafKeyboard","keyboard","map","row","btn","text","callback_data","callbackData"],"mappings":"AAOA,OAAO,SAASA,mBAAmBC,QAAwB;IACzD,OAAOA,SAASC,GAAG,CAAC,CAACC,MACnBA,IAAID,GAAG,CAAC,CAACE,MAAS,CAAA;gBAAEC,MAAMD,IAAIC,IAAI;gBAAEC,eAAeF,IAAIG,YAAY;YAAC,CAAA;AAExE"}
@@ -1 +1 @@
1
- {"version":3,"file":"telegramMarkdown.d.ts","sourceRoot":"","sources":["../../../src/adapters/telegram/telegramMarkdown.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,oBAAoB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAK5D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOpD;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAiBjG;AAqOD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA2BnE"}
1
+ {"version":3,"file":"telegramMarkdown.d.ts","sourceRoot":"","sources":["../../../src/adapters/telegram/telegramMarkdown.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAK5D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOpD;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAiBjG;AAuOD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA2BnE"}
@@ -1,14 +1,14 @@
1
- import { Marked } from 'marked';
2
- import { markdownToTelegramHtml } from './telegramHtml.js';
1
+ import { Marked } from "marked";
2
+ import { markdownToTelegramHtml } from "./telegramHtml.js";
3
3
  const markdownLexer = new Marked();
4
4
  export function isParseEntitiesError(error) {
5
- if (!error || typeof error !== 'object') return false;
5
+ if (!error || typeof error !== "object") return false;
6
6
  const description = error.description;
7
7
  const message = error.message;
8
- return ((description ?? '') + (message ?? '')).includes("can't parse entities");
8
+ return ((description ?? "") + (message ?? "")).includes("can't parse entities");
9
9
  }
10
10
  export function htmlToPlainText(html) {
11
- return html.replace(/<[^>]+>/g, '').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&amp;/g, '&');
11
+ return html.replace(/<[^>]+>/g, "").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
12
12
  }
13
13
  export function chunkMarkdownForTelegram(markdown, maxLen) {
14
14
  const markdownChunks = splitMarkdownSource(markdown, maxLen);
@@ -38,10 +38,10 @@ function splitMarkdownSource(markdown, maxLen, depth = 0) {
38
38
  ];
39
39
  if (depth > 6) return splitPlainMarkdownText(markdown, maxLen);
40
40
  const chunks = [];
41
- let current = '';
41
+ let current = "";
42
42
  const tokens = markdownLexer.lexer(markdown);
43
43
  for (const token of tokens){
44
- const raw = token.raw ?? '';
44
+ const raw = token.raw ?? "";
45
45
  if (raw.length === 0) continue;
46
46
  const candidate = current + raw;
47
47
  if (candidate.length > 0 && renderedLengthFits(candidate, maxLen)) {
@@ -50,7 +50,7 @@ function splitMarkdownSource(markdown, maxLen, depth = 0) {
50
50
  }
51
51
  if (current.length > 0) {
52
52
  chunks.push(current);
53
- current = '';
53
+ current = "";
54
54
  }
55
55
  if (renderedLengthFits(raw, maxLen)) {
56
56
  current = raw;
@@ -65,23 +65,23 @@ function splitMarkdownSource(markdown, maxLen, depth = 0) {
65
65
  }
66
66
  function splitOversizedToken(token, maxLen, depth) {
67
67
  switch(token.type){
68
- case 'code':
68
+ case "code":
69
69
  return splitCodeToken(token, maxLen);
70
- case 'list':
70
+ case "list":
71
71
  return splitListToken(token, maxLen, depth);
72
- case 'paragraph':
73
- case 'text':
72
+ case "paragraph":
73
+ case "text":
74
74
  return splitPlainMarkdownText(token.raw, maxLen);
75
75
  default:
76
- if ('tokens' in token && Array.isArray(token.tokens) && token.raw !== undefined) {
76
+ if ("tokens" in token && Array.isArray(token.tokens) && token.raw !== undefined) {
77
77
  return splitMarkdownSource(token.raw, maxLen, depth);
78
78
  }
79
- return splitPlainMarkdownText(token.raw ?? '', maxLen);
79
+ return splitPlainMarkdownText(token.raw ?? "", maxLen);
80
80
  }
81
81
  }
82
82
  function splitListToken(token, maxLen, depth) {
83
83
  const chunks = [];
84
- let current = '';
84
+ let current = "";
85
85
  for (const item of token.items){
86
86
  const raw = item.raw;
87
87
  const candidate = current + raw;
@@ -91,7 +91,7 @@ function splitListToken(token, maxLen, depth) {
91
91
  }
92
92
  if (current.length > 0) {
93
93
  chunks.push(current);
94
- current = '';
94
+ current = "";
95
95
  }
96
96
  if (renderedLengthFits(raw, maxLen)) {
97
97
  current = raw;
@@ -103,12 +103,12 @@ function splitListToken(token, maxLen, depth) {
103
103
  return chunks;
104
104
  }
105
105
  function splitCodeToken(token, maxLen) {
106
- const fence = token.raw.startsWith('~~~') ? '~~~' : '```';
107
- const lang = token.lang ? token.lang.split(/\s/)[0] : '';
108
- const lines = token.text.split('\n');
106
+ const fence = token.raw.startsWith("~~~") ? "~~~" : "```";
107
+ const lang = token.lang ? token.lang.split(/\s/)[0] : "";
108
+ const lines = token.text.split("\n");
109
109
  const chunks = [];
110
110
  let currentLines = [];
111
- const renderFence = (codeLines)=>`${fence}${lang}\n${codeLines.join('\n')}\n${fence}\n\n`;
111
+ const renderFence = (codeLines)=>`${fence}${lang}\n${codeLines.join("\n")}\n${fence}\n\n`;
112
112
  for (const line of lines){
113
113
  const candidateLines = [
114
114
  ...currentLines,
@@ -141,7 +141,7 @@ function splitCodeToken(token, maxLen) {
141
141
  }
142
142
  function splitCodeLine(line, fence, lang, maxLen) {
143
143
  const segments = [];
144
- let current = '';
144
+ let current = "";
145
145
  const renderFence = (value)=>`${fence}${lang}\n${value}\n${fence}\n\n`;
146
146
  for (const char of Array.from(line)){
147
147
  const candidate = current + char;
@@ -151,7 +151,7 @@ function splitCodeLine(line, fence, lang, maxLen) {
151
151
  }
152
152
  if (current.length > 0) {
153
153
  segments.push(current);
154
- current = '';
154
+ current = "";
155
155
  }
156
156
  if (renderedLengthFits(renderFence(char), maxLen)) {
157
157
  current = char;
@@ -183,7 +183,7 @@ function splitPlainMarkdownText(markdown, maxLen) {
183
183
  }
184
184
  function packMarkdownUnits(units, maxLen, splitOversized) {
185
185
  const chunks = [];
186
- let current = '';
186
+ let current = "";
187
187
  for (const unit of units){
188
188
  const candidate = current + unit;
189
189
  if (renderedLengthFits(candidate, maxLen)) {
@@ -192,7 +192,7 @@ function packMarkdownUnits(units, maxLen, splitOversized) {
192
192
  }
193
193
  if (current.length > 0) {
194
194
  chunks.push(current);
195
- current = '';
195
+ current = "";
196
196
  }
197
197
  if (renderedLengthFits(unit, maxLen)) {
198
198
  current = unit;
@@ -205,7 +205,7 @@ function packMarkdownUnits(units, maxLen, splitOversized) {
205
205
  }
206
206
  function splitByCodePoint(text, maxLen) {
207
207
  const chunks = [];
208
- let current = '';
208
+ let current = "";
209
209
  for (const char of Array.from(text)){
210
210
  const candidate = current + char;
211
211
  if (renderedLengthFits(candidate, maxLen)) {
@@ -214,7 +214,7 @@ function splitByCodePoint(text, maxLen) {
214
214
  }
215
215
  if (current.length > 0) {
216
216
  chunks.push(current);
217
- current = '';
217
+ current = "";
218
218
  }
219
219
  if (renderedLengthFits(char, maxLen)) {
220
220
  current = char;
@@ -239,8 +239,8 @@ function renderedLengthFits(markdown, maxLen) {
239
239
  chunks.push(remaining);
240
240
  break;
241
241
  }
242
- const lastParagraph = remaining.lastIndexOf('\n\n', maxLen - 2);
243
- const lastNewline = remaining.lastIndexOf('\n', maxLen - 1);
242
+ const lastParagraph = remaining.lastIndexOf("\n\n", maxLen - 2);
243
+ const lastNewline = remaining.lastIndexOf("\n", maxLen - 1);
244
244
  let splitAt;
245
245
  if (lastParagraph > 0) {
246
246
  splitAt = lastParagraph + 2;