create-bunspace 0.3.0 → 0.3.1

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 (50) hide show
  1. package/dist/templates/monorepo/apps/example/package.json +1 -1
  2. package/dist/templates/monorepo/core/packages/utils/rolldown.config.ts +30 -0
  3. package/dist/templates/monorepo/tsconfig.json +3 -1
  4. package/dist/templates/telegram-bot/bun.lock +6 -20
  5. package/dist/templates/telegram-bot/core/package.json +11 -0
  6. package/dist/templates/telegram-bot/core/rolldown.config.ts +11 -0
  7. package/dist/templates/telegram-bot/core/src/config/logging.ts +1 -3
  8. package/dist/templates/telegram-bot/core/src/handlers/config-export.ts +10 -9
  9. package/dist/templates/telegram-bot/core/src/handlers/control.ts +30 -21
  10. package/dist/templates/telegram-bot/core/src/handlers/demo-full.ts +58 -0
  11. package/dist/templates/telegram-bot/core/src/handlers/demo-keyboard.ts +49 -0
  12. package/dist/templates/telegram-bot/core/src/handlers/demo-media.ts +163 -0
  13. package/dist/templates/telegram-bot/core/src/handlers/demo-text.ts +27 -0
  14. package/dist/templates/telegram-bot/core/src/handlers/health.ts +22 -14
  15. package/dist/templates/telegram-bot/core/src/handlers/info.ts +21 -23
  16. package/dist/templates/telegram-bot/core/src/handlers/logs.ts +8 -6
  17. package/dist/templates/telegram-bot/core/src/index.ts +20 -1
  18. package/dist/templates/telegram-bot/core/src/utils/formatters.ts +5 -60
  19. package/dist/templates/telegram-bot/core/tsconfig.json +2 -0
  20. package/dist/templates/telegram-bot/package.json +3 -2
  21. package/dist/templates/telegram-bot/packages/utils/package.json +12 -1
  22. package/dist/templates/telegram-bot/packages/utils/rolldown.config.ts +11 -0
  23. package/dist/templates/telegram-bot/packages/utils/tsconfig.json +10 -0
  24. package/dist/templates/telegram-bot/tsconfig.json +7 -2
  25. package/package.json +1 -1
  26. package/templates/monorepo/apps/example/package.json +1 -1
  27. package/templates/monorepo/core/packages/utils/rolldown.config.ts +30 -0
  28. package/templates/monorepo/tsconfig.json +3 -1
  29. package/templates/telegram-bot/bun.lock +6 -20
  30. package/templates/telegram-bot/core/package.json +11 -0
  31. package/templates/telegram-bot/core/rolldown.config.ts +11 -0
  32. package/templates/telegram-bot/core/src/config/logging.ts +1 -3
  33. package/templates/telegram-bot/core/src/handlers/config-export.ts +10 -9
  34. package/templates/telegram-bot/core/src/handlers/control.ts +30 -21
  35. package/templates/telegram-bot/core/src/handlers/demo-full.ts +58 -0
  36. package/templates/telegram-bot/core/src/handlers/demo-keyboard.ts +49 -0
  37. package/templates/telegram-bot/core/src/handlers/demo-media.ts +163 -0
  38. package/templates/telegram-bot/core/src/handlers/demo-text.ts +27 -0
  39. package/templates/telegram-bot/core/src/handlers/health.ts +22 -14
  40. package/templates/telegram-bot/core/src/handlers/info.ts +21 -23
  41. package/templates/telegram-bot/core/src/handlers/logs.ts +8 -6
  42. package/templates/telegram-bot/core/src/index.ts +20 -1
  43. package/templates/telegram-bot/core/src/utils/formatters.ts +5 -60
  44. package/templates/telegram-bot/core/tsconfig.json +2 -0
  45. package/templates/telegram-bot/package.json +3 -2
  46. package/templates/telegram-bot/packages/utils/package.json +12 -1
  47. package/templates/telegram-bot/packages/utils/rolldown.config.ts +11 -0
  48. package/templates/telegram-bot/packages/utils/tsconfig.json +10 -0
  49. package/templates/telegram-bot/tsconfig.json +7 -2
  50. package/templates/telegram-bot/core/src/utils/message-builder.ts +0 -180
@@ -1,6 +1,6 @@
1
1
  import type { Context } from 'telegraf'
2
2
  import { infoLogger, badge, kv, colors, colorText } from '../middleware/logging.js'
3
- import { MessageBuilder } from '../utils/message-builder.js'
3
+ import { TelegramMessageBuilder } from '@mks2508/telegram-message-builder'
4
4
 
5
5
  export async function handleGetInfo(ctx: Context): Promise<void> {
6
6
  const userId = ctx.from?.id ?? 'unknown'
@@ -17,16 +17,14 @@ export async function handleGetInfo(ctx: Context): Promise<void> {
17
17
  const from = ctx.from
18
18
  const chat = ctx.chat
19
19
 
20
- const builder = MessageBuilder.markdown()
21
-
22
- // Title
23
- builder.title('📋 Your Information')
24
- builder.newline()
20
+ const builder = TelegramMessageBuilder.text()
21
+ .title('📋 Your Information')
22
+ .newline()
25
23
 
26
24
  // User info
27
25
  if (from) {
28
26
  builder.section('👤 User Info:')
29
- builder.line('User ID', String(from.id), { code: true })
27
+ .line('User ID', String(from.id), { code: true })
30
28
  if (from.username) builder.line('Username', `@${from.username}`)
31
29
  if (from.first_name) builder.line('First Name', from.first_name)
32
30
  if (from.last_name) builder.line('Last Name', from.last_name)
@@ -38,8 +36,8 @@ export async function handleGetInfo(ctx: Context): Promise<void> {
38
36
  // Chat info
39
37
  if (chat) {
40
38
  builder.section('💬 Chat Info:')
41
- builder.line('Chat ID', String(chat.id), { code: true })
42
- builder.line('Type', chat.type)
39
+ .line('Chat ID', String(chat.id), { code: true })
40
+ .line('Type', chat.type)
43
41
  if ('title' in chat && chat.title) builder.line('Title', chat.title)
44
42
  if ('username' in chat && chat.username) builder.line('Username', `@${chat.username}`)
45
43
  if (chat.type === 'supergroup' || chat.type === 'group') {
@@ -53,7 +51,7 @@ export async function handleGetInfo(ctx: Context): Promise<void> {
53
51
  const botMention = detectBotMention(msg as unknown as MaybeMessage, botUsername)
54
52
  if (botMention.isMentioned) {
55
53
  builder.section('🤖 Bot Mention:')
56
- builder.line('Bot mentioned', 'Yes')
54
+ .line('Bot mentioned', 'Yes')
57
55
  if (botMention.type) builder.line('Mention type', botMention.type)
58
56
  if (botMention.replyToBot) builder.text('Replying to bot message')
59
57
  builder.newline()
@@ -64,7 +62,7 @@ export async function handleGetInfo(ctx: Context): Promise<void> {
64
62
  // Message/Topic info
65
63
  if (msg) {
66
64
  builder.section('📮 Message Info:')
67
- builder.line('Message ID', String(msg.message_id))
65
+ .line('Message ID', String(msg.message_id))
68
66
  if ('reply_to_message' in msg && msg.reply_to_message) {
69
67
  const replyTo = msg.reply_to_message
70
68
  builder.line('Reply to message ID', String(replyTo.message_id))
@@ -75,31 +73,31 @@ export async function handleGetInfo(ctx: Context): Promise<void> {
75
73
  const threadId = getThreadId(msg as unknown as MaybeMessage)
76
74
  if (threadId) {
77
75
  builder.newline()
78
- builder.section('🧵 Thread/Topic:')
79
- builder.line('Thread ID', String(threadId), { code: true })
80
- builder.text('This message is in a topic')
81
- builder.newline()
76
+ .section('🧵 Thread/Topic:')
77
+ .line('Thread ID', String(threadId), { code: true })
78
+ .text('This message is in a topic')
79
+ .newline()
82
80
  infoLogger.info(`Message sent in thread ${threadId} by user ${userId}`)
83
81
  }
84
82
 
85
83
  // Configuration tips
86
84
  builder.newline()
87
- builder.section('🔧 Configuration:')
88
- builder.line('TG_CONTROL_CHAT_ID', String(chat?.id ?? 'N/A'), { code: true })
89
- builder.line('TG_AUTHORIZED_USER_IDS', String(from?.id ?? 'N/A'))
85
+ .section('🔧 Configuration:')
86
+ .line('TG_CONTROL_CHAT_ID', String(chat?.id ?? 'N/A'), { code: true })
87
+ .line('TG_AUTHORIZED_USER_IDS', String(from?.id ?? 'N/A'))
90
88
  if (threadId) {
91
89
  builder.line('TG_CONTROL_TOPIC_ID', String(threadId), { code: true })
92
90
  }
93
91
 
94
92
  builder.newline()
95
- builder.text('💡 Copy these values to your .env file')
96
- builder.newline()
97
- builder.newline()
98
- builder.text('💡 Tip: In groups, you can also mention the bot with @username to get this info')
93
+ .text('💡 Copy these values to your .env file')
94
+ .newline()
95
+ .newline()
96
+ .text('💡 Tip: In groups, you can also mention the bot with @username to get this info')
99
97
 
100
98
  const message = builder.build()
101
99
  infoLogger.info(`Replying to user ${userId} with info`)
102
- await ctx.reply(message, { parse_mode: builder.getParseMode() })
100
+ await ctx.reply(message.text || '', { parse_mode: (message.parse_mode || 'HTML') as any })
103
101
  infoLogger.success(`Info sent to user ${userId}`)
104
102
  }
105
103
 
@@ -2,7 +2,7 @@ import type { Context, Telegraf } from 'telegraf'
2
2
  import { getConfig, hasLoggingConfigured } from '../config/index.js'
3
3
  import { streamLogger, botLogger, badge, kv, colors, colorText } from '../middleware/logging.js'
4
4
  import { formatLogEntry } from '../utils/formatters.js'
5
- import { MessageBuilder } from '../utils/message-builder.js'
5
+ import { TelegramMessageBuilder } from '@mks2508/telegram-message-builder'
6
6
 
7
7
  const LOG_BUFFER_SIZE = 10
8
8
  const LOG_BUFFER_TIMEOUT = 5000
@@ -103,9 +103,10 @@ export async function handleLogsCommand(ctx: Context): Promise<void> {
103
103
  const config = getConfig()
104
104
 
105
105
  if (!hasLoggingConfigured()) {
106
- const builder = MessageBuilder.markdown()
106
+ const message = TelegramMessageBuilder.text()
107
107
  .text('❌ Logging is not configured. Set TG_LOG_CHAT_ID environment variable.')
108
- ctx.reply(builder.build(), { parse_mode: builder.getParseMode() })
108
+ .build()
109
+ ctx.reply(message.text || '', { parse_mode: (message.parse_mode || 'HTML') as any })
109
110
  return
110
111
  }
111
112
 
@@ -120,8 +121,8 @@ export async function handleLogsCommand(ctx: Context): Promise<void> {
120
121
  })}`
121
122
  )
122
123
 
123
- const builder = MessageBuilder.markdown()
124
- .title('📝 Log Streaming Status:')
124
+ const builder = TelegramMessageBuilder.text()
125
+ .title('📝 Log Streaming Status')
125
126
  .newline()
126
127
  .line('Status', status, { code: true })
127
128
  .line('Chat ID', String(config.logChatId), { code: true })
@@ -129,5 +130,6 @@ export async function handleLogsCommand(ctx: Context): Promise<void> {
129
130
  builder.line('Topic ID', String(config.logTopicId), { code: true })
130
131
  }
131
132
 
132
- ctx.reply(builder.build(), { parse_mode: builder.getParseMode() })
133
+ const message = builder.build()
134
+ ctx.reply(message.text || '', { parse_mode: (message.parse_mode || 'HTML') as any })
133
135
  }
@@ -10,6 +10,10 @@ import { handleGetInfo } from './handlers/info.js'
10
10
  import { handleStop, handleRestart, handleMode, handleWebhook } from './handlers/control.js'
11
11
  import { handleLogsCommand, initializeLogStreamer } from './handlers/logs.js'
12
12
  import { handleExportConfig } from './handlers/config-export.js'
13
+ import { handleTextDemo } from './handlers/demo-text.js'
14
+ import { handleKeyboardDemo, handleKeyboardCallback } from './handlers/demo-keyboard.js'
15
+ import { handleMediaDemo, handleMediaCallback } from './handlers/demo-media.js'
16
+ import { handleFullDemo, handleFullDemoCallback } from './handlers/demo-full.js'
13
17
  import { auth } from './middleware/auth.js'
14
18
  import { initializeFileLogging } from './config/logging.js'
15
19
 
@@ -75,7 +79,12 @@ async function main(): Promise<void> {
75
79
  '/stats - Show statistics\n' +
76
80
  '/logs - Check log streaming status\n' +
77
81
  '/getinfo - Get your user/chat info for configuration\n' +
78
- '/mode - Check or change bot mode',
82
+ '/mode - Check or change bot mode\n\n' +
83
+ '*🎨 Demo Commands (telegram-message-builder):*\n' +
84
+ '/textdemo - Text formatting showcase\n' +
85
+ '/keybdemo - Keyboard builder showcase\n' +
86
+ '/mediademo - Media types showcase\n' +
87
+ '/fulldemo - Complete feature demo',
79
88
  { parse_mode: 'Markdown' }
80
89
  )
81
90
  botManager.incrementMessages()
@@ -137,6 +146,16 @@ async function main(): Promise<void> {
137
146
 
138
147
  bot.command('logs', handleLogsCommand)
139
148
 
149
+ // Demo commands for telegram-message-builder showcase
150
+ bot.command('textdemo', handleTextDemo)
151
+ bot.command('keybdemo', handleKeyboardDemo)
152
+ bot.command('mediademo', handleMediaDemo)
153
+ bot.command('fulldemo', handleFullDemo)
154
+
155
+ // Callback handlers for demo keyboards
156
+ bot.action(/^(demo_yes|demo_no|demo_refresh|demo_search|full_demo_keyboard)$/, handleKeyboardCallback)
157
+ bot.action(/^(media_photo|media_video|media_document|media_audio|media_voice|full_demo_media)$/, handleMediaCallback)
158
+
140
159
  process.once('SIGINT', async () => {
141
160
  botLogger.info(`${badge('SHUTDOWN', 'pill')} ${colorText('SIGINT received', colors.warning)}`)
142
161
  await instanceManager.releaseLock()
@@ -1,13 +1,9 @@
1
1
  import { TimeConstants } from '../types/constants.js'
2
2
  import type { BotStatus } from '../types/bot.js'
3
- import { MessageBuilder, fmt, escapeText, type FormatType } from './message-builder.js'
3
+ import { TelegramMessageBuilder, fmt } from '@mks2508/telegram-message-builder'
4
4
 
5
- // Re-export MessageBuilder utilities for convenience
6
- export { MessageBuilder, fmt, escapeText }
7
- export type { FormatType }
8
-
9
- // Default format mode for the bot (HTML is simpler and more reliable than MarkdownV2)
10
- export const DEFAULT_FORMAT_MODE: FormatType = 'html'
5
+ // Re-export fmt from telegram-message-builder for convenience
6
+ export { fmt }
11
7
 
12
8
  /**
13
9
  * Format uptime in human-readable format
@@ -45,41 +41,7 @@ export function formatMemory(memoryUsage: {
45
41
  }
46
42
 
47
43
  /**
48
- * Format health status message using MessageBuilder
49
- */
50
- export function formatHealthMessage(status: BotStatus): string {
51
- return MessageBuilder.markdown()
52
- .title('🏥 Bot Health Status')
53
- .newline()
54
- .line('Status', status.status.toUpperCase(), { bold: true })
55
- .line('Mode', status.mode.toUpperCase())
56
- .line('Uptime', formatUptime(status.uptime))
57
- .newline()
58
- .title('Memory Usage')
59
- .text(formatMemory(status.memoryUsage))
60
- .build()
61
- }
62
-
63
- /**
64
- * Format bot statistics using MessageBuilder
65
- */
66
- export function formatStats(stats: {
67
- messagesProcessed: number
68
- commandsExecuted: number
69
- errorsEncountered: number
70
- }): string {
71
- return MessageBuilder.markdown()
72
- .title('📊 Bot Statistics')
73
- .newline()
74
- .section('Performance')
75
- .line('Messages Processed', String(stats.messagesProcessed))
76
- .line('Commands Executed', String(stats.commandsExecuted))
77
- .line('Errors Encountered', String(stats.errorsEncountered))
78
- .build()
79
- }
80
-
81
- /**
82
- * Format a log entry message
44
+ * Format a log entry message for Telegram
83
45
  */
84
46
  export function formatLogEntry(
85
47
  timestamp: string,
@@ -97,22 +59,5 @@ export function formatLogEntry(
97
59
 
98
60
  const emoji = levelEmoji[level as keyof typeof levelEmoji] || 'ℹ️'
99
61
 
100
- return MessageBuilder.markdown()
101
- .text(`${emoji} [${component}] `)
102
- .text(message)
103
- .newline()
104
- .text(fmt.italic(timestamp))
105
- .build()
106
- }
107
-
108
- /**
109
- * Format error message
110
- */
111
- export function formatError(error: Error | string): string {
112
- const message = error instanceof Error ? error.message : String(error)
113
- return MessageBuilder.markdown()
114
- .text('❌ ')
115
- .title('Error:')
116
- .text(message)
117
- .build()
62
+ return `${emoji} [${component}] ${message}\n${fmt.italic(timestamp)}`
118
63
  }
@@ -2,6 +2,8 @@
2
2
  "extends": "../tsconfig.json",
3
3
  "compilerOptions": {
4
4
  "rootDir": ".",
5
+ "outDir": "./dist",
6
+ "declarationDir": "./dist",
5
7
  "types": ["bun-types", "node"]
6
8
  },
7
9
  "include": ["src/**/*.ts"],
@@ -5,7 +5,7 @@
5
5
  "type": "module",
6
6
  "workspaces": [
7
7
  "core",
8
- "apps/*"
8
+ "packages/*"
9
9
  ],
10
10
  "scripts": {
11
11
  "dev": "bun run --filter @mks2508/telegram-bot-core dev",
@@ -39,7 +39,8 @@
39
39
  "typescript": "^5"
40
40
  },
41
41
  "dependencies": {
42
- "@flla/telegram-format": "^3.1.2",
42
+ "@mks2508/telegram-message-builder": "0.3.1",
43
+ "@mks2508/telegram-bot-utils": "workspace:*",
43
44
  "@inquirer/prompts": "^8.1.0",
44
45
  "chalk": "^5.6.2",
45
46
  "commander": "^14.0.2",
@@ -2,11 +2,22 @@
2
2
  "name": "@mks2508/telegram-bot-utils",
3
3
  "version": "0.1.0",
4
4
  "type": "module",
5
+ "scripts": {
6
+ "build": "rolldown --config rolldown.config.ts && tsgo --emitDeclarationOnly",
7
+ "dev": "bun run --watch src/index.ts",
8
+ "typecheck": "tsgo --noEmit"
9
+ },
5
10
  "exports": {
6
- ".": "./src/index.ts"
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
7
15
  },
8
16
  "dependencies": {
9
17
  "@mks2508/better-logger": "^4.0.0",
10
18
  "@mks2508/no-throw": "^0.1.0"
19
+ },
20
+ "devDependencies": {
21
+ "rolldown": "^1.0.0-beta.58"
11
22
  }
12
23
  }
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from 'rolldown';
2
+
3
+ export default defineConfig({
4
+ input: './src/index.ts',
5
+ output: {
6
+ file: './dist/index.js',
7
+ format: 'esm',
8
+ sourcemap: true,
9
+ },
10
+ external: ['@mks2508/better-logger', '@mks2508/no-throw'],
11
+ });
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "rootDir": "./src",
5
+ "outDir": "./dist",
6
+ "declarationDir": "./dist"
7
+ },
8
+ "include": ["src/**/*.ts"],
9
+ "exclude": ["node_modules", "dist"]
10
+ }
@@ -8,7 +8,7 @@
8
8
  "moduleResolution": "bundler",
9
9
  "allowImportingTsExtensions": true,
10
10
  "verbatimModuleSyntax": true,
11
- "noEmit": true,
11
+ "noEmit": false,
12
12
  "strict": true,
13
13
  "skipLibCheck": true,
14
14
  "noFallthroughCasesInSwitch": true,
@@ -16,7 +16,12 @@
16
16
  "noImplicitOverride": true,
17
17
  "noUnusedLocals": false,
18
18
  "noUnusedParameters": false,
19
- "noPropertyAccessFromIndexSignature": false
19
+ "noPropertyAccessFromIndexSignature": false,
20
+ "declaration": true,
21
+ "declarationMap": true,
22
+ "sourceMap": true,
23
+ "outDir": "./dist",
24
+ "declarationDir": "./dist"
20
25
  },
21
26
  "exclude": ["node_modules", "**/node_modules", "**/dist"]
22
27
  }
@@ -1,180 +0,0 @@
1
- import telegramFormat from '@flla/telegram-format'
2
- import type { Formatter } from '@flla/telegram-format'
3
-
4
- // Get the formatters from the main module
5
- const { html } = telegramFormat
6
-
7
- /**
8
- * MessageBuilder - Fluent API for building formatted Telegram messages
9
- *
10
- * Provides a consistent way to build messages without worrying about:
11
- * - Proper escaping of special characters
12
- * - Format consistency (Markdown vs HTML)
13
- * - Parse errors from malformed entities
14
- *
15
- * @example
16
- * ```typescript
17
- * const message = MessageBuilder.markdown()
18
- * .title('User Information')
19
- * .newline()
20
- * .line('User ID', '123456', { code: true })
21
- * .line('Username', '@john_doe')
22
- * .build()
23
- * ```
24
- */
25
- export class MessageBuilder {
26
- private parts: string[] = []
27
- private listDepth = 0
28
-
29
- private constructor(
30
- private formatter: Formatter,
31
- private parseModeValue: 'Markdown' | 'HTML' | 'MarkdownV2'
32
- ) {}
33
-
34
- /**
35
- * Create an HTML message builder (default)
36
- * HTML is simpler and more reliable than MarkdownV2
37
- */
38
- static markdown(): MessageBuilder {
39
- return new MessageBuilder(html as unknown as Formatter, 'HTML')
40
- }
41
-
42
- /**
43
- * Create an HTML message builder
44
- */
45
- static html(): MessageBuilder {
46
- return new MessageBuilder(html as unknown as Formatter, 'HTML')
47
- }
48
-
49
- /**
50
- * Add a title/heading (bold)
51
- */
52
- title(text: string): this {
53
- this.parts.push(this.formatter.bold(text))
54
- return this
55
- }
56
-
57
- /**
58
- * Add a section heading (underline/italic)
59
- */
60
- section(text: string): this {
61
- this.parts.push(this.formatter.underline(text))
62
- return this
63
- }
64
-
65
- /**
66
- * Add a key-value line
67
- * @param key - The label/key
68
- * @param value - The value
69
- * @param opts - Options for formatting the value
70
- */
71
- line(key: string, value: string, opts?: { code?: boolean; bold?: boolean }): this {
72
- let formattedValue = value
73
- if (opts?.code) {
74
- formattedValue = this.formatter.monospace(value)
75
- } else if (opts?.bold) {
76
- formattedValue = this.formatter.bold(value)
77
- }
78
- this.parts.push(`${key}: ${formattedValue}`)
79
- return this
80
- }
81
-
82
- /**
83
- * Add a code block
84
- */
85
- codeBlock(text: string, language?: string): this {
86
- this.parts.push(this.formatter.monospaceBlock(text, language))
87
- return this
88
- }
89
-
90
- /**
91
- * Add a list item
92
- */
93
- listItem(text: string, depth: number = 0): this {
94
- const indent = ' '.repeat(depth)
95
- const bullet = this.listDepth > 0 ? '•' : `${this.listDepth + 1}.`
96
- this.parts.push(`${indent}${bullet} ${text}`)
97
- return this
98
- }
99
-
100
- /**
101
- * Add a sublist (increase indentation)
102
- */
103
- startSublist(): this {
104
- this.listDepth++
105
- return this
106
- }
107
-
108
- /**
109
- * End sublist (decrease indentation)
110
- */
111
- endSublist(): this {
112
- if (this.listDepth > 0) this.listDepth--
113
- return this
114
- }
115
-
116
- /**
117
- * Add a newline
118
- */
119
- newline(): this {
120
- this.parts.push('\n')
121
- return this
122
- }
123
-
124
- /**
125
- * Add raw text (escaped, no formatting)
126
- */
127
- text(text: string): this {
128
- this.parts.push(this.formatter.escape(text))
129
- return this
130
- }
131
-
132
- /**
133
- * Add a horizontal rule (separator)
134
- */
135
- separator(): this {
136
- this.parts.push(this.parseModeValue === 'HTML' ? '<hr>' : '---')
137
- return this
138
- }
139
-
140
- /**
141
- * Build the final message string
142
- * @returns The formatted message ready to send
143
- */
144
- build(): string {
145
- return this.parts.join('\n').trim()
146
- }
147
-
148
- /**
149
- * Get the parse_mode for Telegraf
150
- * Note: Telegraf accepts 'Markdown' for both Markdown and MarkdownV2
151
- */
152
- getParseMode(): 'Markdown' | 'HTML' {
153
- return this.parseModeValue === 'MarkdownV2' ? 'Markdown' : this.parseModeValue
154
- }
155
- }
156
-
157
- /**
158
- * Quick escape helper for raw text
159
- */
160
- export function escapeText(text: string): string {
161
- const formatter = html as unknown as Formatter
162
- return formatter.escape(text)
163
- }
164
-
165
- /**
166
- * Format mode type
167
- */
168
- export type FormatType = 'html'
169
-
170
- /**
171
- * Quick format helpers
172
- */
173
- export const fmt = {
174
- bold: (text: string) => (html as unknown as Formatter).bold(text),
175
- italic: (text: string) => (html as unknown as Formatter).italic(text),
176
- underline: (text: string) => (html as unknown as Formatter).underline(text),
177
- code: (text: string) => (html as unknown as Formatter).monospace(text),
178
- link: (text: string, url: string) => (html as unknown as Formatter).url(text, url),
179
- escape: (text: string) => (html as unknown as Formatter).escape(text),
180
- }