{"_id":"@abdulgalimov/telegram","_rev":"12-75ad6cda964dc7613339693db672877b","name":"@abdulgalimov/telegram","dist-tags":{"latest":"0.0.13"},"versions":{"0.0.1":{"name":"@abdulgalimov/telegram","version":"0.0.1","keywords":["telegram","bot","framework","typescript","grammyjs"],"author":{"name":"abdulgalimov"},"license":"MIT","_id":"@abdulgalimov/telegram@0.0.1","maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"homepage":"https://github.com/abdulgalimov/tg-framework#readme","bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"bin":{"tg-framework":"dist/cli.js"},"dist":{"shasum":"05229a09ea7f5522b475705613fd3efbe44aaa23","tarball":"https://registry.npmjs.org/@abdulgalimov/telegram/-/telegram-0.0.1.tgz","fileCount":10,"integrity":"sha512-lUT5EsjLl3qsIqkbx6DMrk3BhjS83W39wX92Dq8rq039ZYA4+voOtHejkwp9Zb+5PqINz3O5mJsiEeIc7UrA6w==","signatures":[{"sig":"MEYCIQDgYsRFOobnanMTg3SmxXd70IzYWHpbeVZ+H6sdPwo7EgIhAMGUAAlqYV3ym08qKyQwQ7rSB+3tvHYe61slQ3F2TG8v","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":236117},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./*":{"import":"./dist/*.js","require":"./dist/*.js"},"./package.json":{"default":"./package.json"}},"gitHead":"39aba1762dab7c2e529d57a142bd13437dd7e332","scripts":{"build":"tsdown","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm run build"},"_npmUser":{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"},"repository":{"url":"git+https://github.com/abdulgalimov/tg-framework.git","type":"git"},"_npmVersion":"11.6.2","description":"TypeScript framework for building Telegram bots","directories":{},"_nodeVersion":"22.16.0","dependencies":{"uuid":"^11.1.0"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.21.2","prettier":"^3.8.1","typescript":"^5.7.3","@types/node":"^25.5.0","@grammyjs/types":"^3.16.0"},"peerDependencies":{"@grammyjs/types":"^3.16.0"},"_npmOperationalInternal":{"tmp":"tmp/telegram_0.0.1_1774182449741_0.8461759198152432","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@abdulgalimov/telegram","version":"0.0.2","keywords":["telegram","bot","framework","typescript","grammyjs"],"author":{"name":"abdulgalimov"},"license":"MIT","_id":"@abdulgalimov/telegram@0.0.2","maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"homepage":"https://github.com/abdulgalimov/tg-framework#readme","bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"bin":{"telegram-prepare":"dist/cli.js"},"dist":{"shasum":"22b023c72da81c1873e2b4ea01c01251739415b4","tarball":"https://registry.npmjs.org/@abdulgalimov/telegram/-/telegram-0.0.2.tgz","fileCount":10,"integrity":"sha512-tJC2k4g7wJ5MgezKVkrZd8zzIFczNsqVuiPKwCMWaT/IQuqgCszPufXIvm6bOsYhjTAgriObt/PxnQoZWJK+dA==","signatures":[{"sig":"MEUCIBP9MUWrXnbaCeTwL4Dg4BDM4V+LbD8hsSUzY1uo9IKfAiEAmxNQCKKoCHly6IH6x0xBkAHtllUoFvr79Ka0D3rcdLo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":236102},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./*":{"import":"./dist/*.js","require":"./dist/*.js"},"./package.json":{"default":"./package.json"}},"gitHead":"39aba1762dab7c2e529d57a142bd13437dd7e332","scripts":{"build":"tsdown","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm run build"},"_npmUser":{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"},"repository":{"url":"git+https://github.com/abdulgalimov/tg-framework.git","type":"git"},"_npmVersion":"11.6.2","description":"TypeScript framework for building Telegram bots","directories":{},"_nodeVersion":"22.16.0","dependencies":{"uuid":"^11.1.0"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.21.2","prettier":"^3.8.1","typescript":"^5.7.3","@types/node":"^25.5.0","@grammyjs/types":"^3.16.0"},"peerDependencies":{"@grammyjs/types":"^3.16.0"},"_npmOperationalInternal":{"tmp":"tmp/telegram_0.0.2_1774182608883_0.8031562822034539","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@abdulgalimov/telegram","version":"0.0.3","keywords":["telegram","bot","framework","typescript","grammyjs"],"author":{"name":"abdulgalimov"},"license":"MIT","_id":"@abdulgalimov/telegram@0.0.3","maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"homepage":"https://github.com/abdulgalimov/tg-framework#readme","bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"bin":{"telegram-prepare":"dist/cli.js"},"dist":{"shasum":"6154600c0f8da82b696ec0d3fcb8f79ed072d207","tarball":"https://registry.npmjs.org/@abdulgalimov/telegram/-/telegram-0.0.3.tgz","fileCount":10,"integrity":"sha512-y9hKOthIW/YuVS1iDbQvOeF9qGTDmsFkHaz4wL1F3I9FRxGwHtT2L67LYTOuvhpvHL5JaA97cBLX/Y66Q3PUvA==","signatures":[{"sig":"MEYCIQC/xqLjp0EwM47CbEi9+Xyw1pOFQewmwQsYBy1qQRKNSwIhAMvIyDRqOk8zYBGcS1oXbYSe057WBzNXZe7HDwFo5rSW","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":253158},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./*":{"import":"./dist/*.js","require":"./dist/*.js"},"./package.json":{"default":"./package.json"}},"gitHead":"36aece8a077ff593ad3b415bd8ea2eafbc992042","scripts":{"build":"tsdown","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm run build"},"_npmUser":{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"},"repository":{"url":"git+https://github.com/abdulgalimov/tg-framework.git","type":"git"},"_npmVersion":"11.6.2","description":"TypeScript framework for building Telegram bots","directories":{},"_nodeVersion":"22.16.0","dependencies":{"uuid":"^11.1.0"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.21.2","prettier":"^3.8.1","typescript":"^5.7.3","@types/node":"^25.5.0","@grammyjs/types":"^3.16.0"},"peerDependencies":{"@grammyjs/types":"^3.16.0"},"_npmOperationalInternal":{"tmp":"tmp/telegram_0.0.3_1774184958227_0.8468345709704805","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@abdulgalimov/telegram","version":"0.0.5","keywords":["telegram","bot","framework","typescript","grammyjs"],"author":{"name":"abdulgalimov"},"license":"MIT","_id":"@abdulgalimov/telegram@0.0.5","maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"homepage":"https://github.com/abdulgalimov/tg-framework#readme","bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"bin":{"telegram-prepare":"dist/cli.js"},"dist":{"shasum":"dc687a8ec836cddb6e510fd7ce75676ed98303b8","tarball":"https://registry.npmjs.org/@abdulgalimov/telegram/-/telegram-0.0.5.tgz","fileCount":10,"integrity":"sha512-gz55yL3u7EeGARgTBPVeJdazd7pGBShRQyG8CjPCt8UaM2GwAtHuoLZzNxzitaKjSjIY9OglqhEViWyU6Sn4yg==","signatures":[{"sig":"MEYCIQCh+XQA5vNOHULKyFdatzEq4ijP7Q31r2iwYm4HBAgkuQIhAIN0woU5f12ygvETflwJPJMr8tvwiygRCvggtRCiHotl","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":261340},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./*":{"import":"./dist/*.js","require":"./dist/*.js"},"./package.json":{"default":"./package.json"}},"gitHead":"e01029e5fcd316e9ccdea2ca85c1b9d5ecc761f7","scripts":{"pub":"npm publish --access public --userconfig .npmrc","build":"tsdown","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm run build"},"_npmUser":{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"},"repository":{"url":"git+https://github.com/abdulgalimov/tg-framework.git","type":"git"},"_npmVersion":"11.6.2","description":"TypeScript framework for building Telegram bots","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.21.2","prettier":"^3.8.1","typescript":"^5.7.3","@types/node":"^25.5.0","@grammyjs/types":"^3.16.0"},"peerDependencies":{"@grammyjs/types":"^3.16.0"},"_npmOperationalInternal":{"tmp":"tmp/telegram_0.0.5_1774467185459_0.15101052193759723","host":"s3://npm-registry-packages-npm-production"}},"0.0.6":{"name":"@abdulgalimov/telegram","version":"0.0.6","keywords":["telegram","bot","framework","typescript","grammyjs"],"author":{"name":"abdulgalimov"},"license":"MIT","_id":"@abdulgalimov/telegram@0.0.6","maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"homepage":"https://github.com/abdulgalimov/tg-framework#readme","bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"bin":{"telegram-prepare":"dist/cli.js"},"dist":{"shasum":"c094e3a92a8c2d23f634abb77c58493eb787aa45","tarball":"https://registry.npmjs.org/@abdulgalimov/telegram/-/telegram-0.0.6.tgz","fileCount":10,"integrity":"sha512-p5RXXcHX+Rik/C0fXws6vPucfwbVbvyH37dfRt0Plb+S/+3Lu4RC7ow8K4eDX6p9sZtg2dyLh01LgDbXfuC9Cg==","signatures":[{"sig":"MEUCIGjch9gTzOjpnSNAQhaJ5laCkc/wiqIZlAovTEumblzEAiEA3Kqnh0si9BVnkjRI4H1x4ol822kQlZU1a//7dqjZ0S4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":261385},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./*":{"import":"./dist/*.js","require":"./dist/*.js"},"./package.json":{"default":"./package.json"}},"gitHead":"551f9816ee58164cf9234da9a787219bf8166238","scripts":{"pub":"npm publish --access public --userconfig .npmrc","build":"tsdown","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm run build"},"_npmUser":{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"},"repository":{"url":"git+https://github.com/abdulgalimov/tg-framework.git","type":"git"},"_npmVersion":"11.6.2","description":"TypeScript framework for building Telegram bots","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.21.2","prettier":"^3.8.1","typescript":"^5.7.3","@types/node":"^25.5.0","@grammyjs/types":"^3.16.0"},"peerDependencies":{"@grammyjs/types":"^3.16.0"},"_npmOperationalInternal":{"tmp":"tmp/telegram_0.0.6_1774467303642_0.7078780373949181","host":"s3://npm-registry-packages-npm-production"}},"0.0.7":{"name":"@abdulgalimov/telegram","version":"0.0.7","keywords":["telegram","bot","framework","typescript","grammyjs"],"author":{"name":"abdulgalimov"},"license":"MIT","_id":"@abdulgalimov/telegram@0.0.7","maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"homepage":"https://github.com/abdulgalimov/tg-framework#readme","bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"bin":{"telegram-prepare":"dist/cli.js"},"dist":{"shasum":"a83ea88cecc6479403b59b891be0710111604281","tarball":"https://registry.npmjs.org/@abdulgalimov/telegram/-/telegram-0.0.7.tgz","fileCount":10,"integrity":"sha512-xS0o0wvoWxXtqesaFXUMFZHYzBgiwEx0eNIGnPvrQF/2FAaII9soc8k/c/knTX3sNRtRfu2Ya6d9n44cgpTyDQ==","signatures":[{"sig":"MEYCIQDvrPeM1Y7s2goOwEYk2c5qQRRJD8g+hHkuSVHbEBbMEQIhAPeUUxq7Hc3dh93HVuPuRvP52/SkwNnQh8n4Kk6uJZi0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":262197},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./*":{"import":"./dist/*.js","require":"./dist/*.js"},"./package.json":{"default":"./package.json"}},"gitHead":"dfbfeec9221d8d1b28ddfef8a82ec288588c9741","scripts":{"pub":"npm publish --access public --userconfig .npmrc","build":"tsdown","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm run build"},"_npmUser":{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"},"repository":{"url":"git+https://github.com/abdulgalimov/tg-framework.git","type":"git"},"_npmVersion":"11.6.2","description":"TypeScript framework for building Telegram bots","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.21.2","prettier":"^3.8.1","typescript":"^5.7.3","@types/node":"^25.5.0","@grammyjs/types":"^3.16.0"},"peerDependencies":{"@grammyjs/types":"^3.16.0"},"_npmOperationalInternal":{"tmp":"tmp/telegram_0.0.7_1774469481516_0.5119412391743057","host":"s3://npm-registry-packages-npm-production"}},"0.0.8":{"name":"@abdulgalimov/telegram","version":"0.0.8","keywords":["telegram","bot","framework","typescript","grammyjs"],"author":{"name":"abdulgalimov"},"license":"MIT","_id":"@abdulgalimov/telegram@0.0.8","maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"homepage":"https://github.com/abdulgalimov/tg-framework#readme","bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"bin":{"telegram-prepare":"dist/cli.js"},"dist":{"shasum":"db288c79cb9beee73dff954d8ea82baaec8933c3","tarball":"https://registry.npmjs.org/@abdulgalimov/telegram/-/telegram-0.0.8.tgz","fileCount":10,"integrity":"sha512-Y71HTWzLr3cm/94/QGBJSFg0iyn4usqVRiWtXh22qh8Jpw9Smc3N5ZzC1b0nFWQouflAxk0LJGDqc4x4OOa/vg==","signatures":[{"sig":"MEUCIEfMSngN6TkhH6cZewzLOcKfR4En1Tl/j8XyRLqouDiEAiEAjiECOO5mwoHUEre/xmg9+Pm+2Hn7Q1E/mLn3iwD/J9s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":263535},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./*":{"import":"./dist/*.js","require":"./dist/*.js"},"./package.json":{"default":"./package.json"}},"gitHead":"eb83c3f4e0eeadfb34fc982b7dad0e392fc0d101","scripts":{"pub":"npm publish --access public --userconfig .npmrc","build":"tsdown","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm run build"},"_npmUser":{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"},"repository":{"url":"git+https://github.com/abdulgalimov/tg-framework.git","type":"git"},"_npmVersion":"11.6.2","description":"TypeScript framework for building Telegram bots","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.21.2","prettier":"^3.8.1","typescript":"^5.7.3","@types/node":"^25.5.0","@grammyjs/types":"^3.16.0"},"peerDependencies":{"@grammyjs/types":"^3.16.0"},"_npmOperationalInternal":{"tmp":"tmp/telegram_0.0.8_1774471403172_0.6485611582426214","host":"s3://npm-registry-packages-npm-production"}},"0.0.9":{"name":"@abdulgalimov/telegram","version":"0.0.9","keywords":["telegram","bot","framework","typescript","grammyjs"],"author":{"name":"abdulgalimov"},"license":"MIT","_id":"@abdulgalimov/telegram@0.0.9","maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"homepage":"https://github.com/abdulgalimov/tg-framework#readme","bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"bin":{"telegram-prepare":"dist/cli.js"},"dist":{"shasum":"cecef2c130bffb67560759deb7fb9cc635b06fa4","tarball":"https://registry.npmjs.org/@abdulgalimov/telegram/-/telegram-0.0.9.tgz","fileCount":10,"integrity":"sha512-3A7YR8S+TKep+grqWa6Y8TN7P+TVmxkGa+1a8ivBk3x8dv3ZDnNJTUT9SxJmdlRXn+yF6/B1Lvu1wtWip4+ePQ==","signatures":[{"sig":"MEUCIDMksqPX3HoG+5RIWEe4L88cQBlb7PVlS4J4dYXEOIvxAiEA7SJGzC+a3Dkmbt/rWX7lc6mn0Eo84k9LLgDgJDWjAl8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":281834},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./*":{"import":"./dist/*.js","require":"./dist/*.js"},"./package.json":{"default":"./package.json"}},"gitHead":"e4ac80db45ef1b96e5bc052b12f2f87da03d35c6","scripts":{"pub":"npm publish --access public --userconfig .npmrc","build":"tsdown","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm run build"},"_npmUser":{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"},"repository":{"url":"git+https://github.com/abdulgalimov/tg-framework.git","type":"git"},"_npmVersion":"11.6.2","description":"TypeScript framework for building Telegram bots","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.21.2","prettier":"^3.8.1","typescript":"^5.7.3","@types/node":"^25.5.0","@grammyjs/types":"^3.16.0"},"peerDependencies":{"@grammyjs/types":"^3.16.0"},"_npmOperationalInternal":{"tmp":"tmp/telegram_0.0.9_1774560141819_0.84057974907113","host":"s3://npm-registry-packages-npm-production"}},"0.0.10":{"name":"@abdulgalimov/telegram","version":"0.0.10","keywords":["telegram","bot","framework","typescript","grammyjs"],"author":{"name":"abdulgalimov"},"license":"MIT","_id":"@abdulgalimov/telegram@0.0.10","maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"homepage":"https://github.com/abdulgalimov/tg-framework#readme","bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"bin":{"telegram-prepare":"dist/cli.js"},"dist":{"shasum":"316c5d08d0137f7da23d6559dcf4855037c3ba92","tarball":"https://registry.npmjs.org/@abdulgalimov/telegram/-/telegram-0.0.10.tgz","fileCount":10,"integrity":"sha512-k6GE9mRMaeUcOGSNy6cPi+EiRkWAWnF0tR/Ax04xnQ5y6ZOHpbK1dxqIiHalJ/b95RKcFulJiCEJWL75WXR03Q==","signatures":[{"sig":"MEUCIQC+xv8UzrfNqHrPp0Ez2AKM7KnPJROm7FiTmJ0Td0zd7QIgO/FET6sbcTKsOOaVMAiy65zF//fhpmHeqDzdz8834jQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":281835},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./*":{"import":"./dist/*.js","require":"./dist/*.js"},"./package.json":{"default":"./package.json"}},"gitHead":"35cd599c9b92aee280dee98c5ef3525cdce7c019","scripts":{"pub":"npm publish --access public --userconfig .npmrc","build":"tsdown","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm run build"},"_npmUser":{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"},"repository":{"url":"git+https://github.com/abdulgalimov/tg-framework.git","type":"git"},"_npmVersion":"11.6.2","description":"TypeScript framework for building Telegram bots","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.21.2","prettier":"^3.8.1","typescript":"^5.7.3","@types/node":"^25.5.0","@grammyjs/types":"^3.16.0"},"peerDependencies":{"@grammyjs/types":"^3.16.0"},"_npmOperationalInternal":{"tmp":"tmp/telegram_0.0.10_1774560855783_0.9240622860462437","host":"s3://npm-registry-packages-npm-production"}},"0.0.11":{"name":"@abdulgalimov/telegram","version":"0.0.11","keywords":["telegram","bot","framework","typescript","grammyjs"],"author":{"name":"abdulgalimov"},"license":"MIT","_id":"@abdulgalimov/telegram@0.0.11","maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"homepage":"https://github.com/abdulgalimov/tg-framework#readme","bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"bin":{"telegram-prepare":"dist/cli.js"},"dist":{"shasum":"35ceb31dd42da55f3ff4b046e3b0b3430ce0938b","tarball":"https://registry.npmjs.org/@abdulgalimov/telegram/-/telegram-0.0.11.tgz","fileCount":10,"integrity":"sha512-OPSN/+Y3aJqOJYhC5kxAGlFRXZHPKzyIYVx1s3MidqiyC9NmdELZeezkrPwxxw4nSKQjB8nFEjy8qw1CB4QOjQ==","signatures":[{"sig":"MEUCIHGGGe4Gd2+Xu03/zwlMbwnqJShWcCEMcGJFGH57J5ecAiEA5Qsa5h8qs6nx+7wkHcNObzFPTVNTrHFO4PQVV5vYg78=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":283325},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./*":{"import":"./dist/*.js","require":"./dist/*.js"},"./package.json":{"default":"./package.json"}},"gitHead":"e9602f0624818c539d10ed032a8752bf64104fc0","scripts":{"pub":"npm publish --access public --userconfig .npmrc","build":"tsdown","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm run build"},"_npmUser":{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"},"repository":{"url":"git+https://github.com/abdulgalimov/tg-framework.git","type":"git"},"_npmVersion":"11.6.2","description":"TypeScript framework for building Telegram bots","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.21.2","prettier":"^3.8.1","typescript":"^5.7.3","@types/node":"^25.5.0","@grammyjs/types":"^3.16.0"},"peerDependencies":{"@grammyjs/types":"^3.16.0"},"_npmOperationalInternal":{"tmp":"tmp/telegram_0.0.11_1774693286418_0.6997695387792919","host":"s3://npm-registry-packages-npm-production"}},"0.0.12":{"name":"@abdulgalimov/telegram","version":"0.0.12","keywords":["telegram","bot","framework","typescript","grammyjs"],"author":{"name":"abdulgalimov"},"license":"MIT","_id":"@abdulgalimov/telegram@0.0.12","maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"homepage":"https://github.com/abdulgalimov/tg-framework#readme","bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"bin":{"telegram-prepare":"dist/cli.js"},"dist":{"shasum":"cfdbb0665cf5c0cb0f79960cdbc7507c3f85be34","tarball":"https://registry.npmjs.org/@abdulgalimov/telegram/-/telegram-0.0.12.tgz","fileCount":10,"integrity":"sha512-kgWOjBv3QmIdC4cM7t8ZrXYNiee1YOvEAbZ3OR5nW8PL2C8BhKXwxDSIBe17YdUYtwrKQ8PSLD0ErfQ/a8qQ5g==","signatures":[{"sig":"MEUCIGV02wH5269vFJZ5JNlzo1/F/KiBTtEV0UgVMOFZ1exZAiEA1EDB3B+libB2PNAivJgjBNvkK0ZJFrnojKYAdVVoxIw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":284261},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./*":{"import":"./dist/*.js","require":"./dist/*.js"},"./package.json":{"default":"./package.json"}},"gitHead":"55b264f45ed6df1eb0f81994502ace822145cf2d","scripts":{"pub":"npm publish --access public --userconfig .npmrc","build":"tsdown","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm run build"},"_npmUser":{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"},"repository":{"url":"git+https://github.com/abdulgalimov/tg-framework.git","type":"git"},"_npmVersion":"11.6.2","description":"TypeScript framework for building Telegram bots","directories":{},"_nodeVersion":"22.16.0","_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.21.2","prettier":"^3.8.1","typescript":"^5.7.3","@types/node":"^25.5.0","@grammyjs/types":"^3.16.0"},"peerDependencies":{"@grammyjs/types":"^3.16.0"},"_npmOperationalInternal":{"tmp":"tmp/telegram_0.0.12_1774697574620_0.3081817791781174","host":"s3://npm-registry-packages-npm-production"}},"0.0.13":{"name":"@abdulgalimov/telegram","version":"0.0.13","description":"TypeScript framework for building Telegram bots","type":"module","main":"./dist/index.js","bin":{"telegram-prepare":"dist/cli.js"},"types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./*":{"import":"./dist/*.js","require":"./dist/*.js"},"./package.json":{"default":"./package.json"}},"scripts":{"build":"tsdown","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm run build","pub":"npm publish --access public --userconfig .npmrc"},"peerDependencies":{"@grammyjs/types":"^3.27.3"},"devDependencies":{"@grammyjs/types":"^3.27.3","@types/node":"^25.5.0","prettier":"^3.8.1","tsdown":"^0.21.2","typescript":"^5.7.3"},"keywords":["telegram","bot","framework","typescript","grammyjs"],"author":{"name":"abdulgalimov"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/abdulgalimov/tg-framework.git"},"homepage":"https://github.com/abdulgalimov/tg-framework#readme","bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"engines":{"node":">=18"},"gitHead":"321cc4c2939562b5813a6c2364f8c1e679879d8b","_id":"@abdulgalimov/telegram@0.0.13","_nodeVersion":"22.16.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-yV7aO/zTNM5ssaX2dsGEz2JBtsdJa5RH9SrGWJxo2zGe7aUYQcWYgv+50ZTsMdR4OzQV+JFIe8/sQeMNqQwVOQ==","shasum":"c13dd1a56ff5109bd1a1c7f1590dd0e68d11540b","tarball":"https://registry.npmjs.org/@abdulgalimov/telegram/-/telegram-0.0.13.tgz","fileCount":10,"unpackedSize":284261,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCNBxTXf0CoCUUXzdgQB/OXdv47uEUIYvE0PRmhqoVGEgIga5ddCzWR9zA1maajuLFaEEgRA3/uafslAxAnPzILgAo="}]},"_npmUser":{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"},"directories":{},"maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/telegram_0.0.13_1779031375224_0.4782716253028976"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-22T12:27:29.686Z","modified":"2026-05-17T15:22:55.474Z","0.0.1":"2026-03-22T12:27:29.888Z","0.0.2":"2026-03-22T12:30:09.018Z","0.0.3":"2026-03-22T13:09:18.391Z","0.0.5":"2026-03-25T19:33:05.609Z","0.0.6":"2026-03-25T19:35:03.839Z","0.0.7":"2026-03-25T20:11:21.677Z","0.0.8":"2026-03-25T20:43:23.346Z","0.0.9":"2026-03-26T21:22:22.012Z","0.0.10":"2026-03-26T21:34:15.959Z","0.0.11":"2026-03-28T10:21:26.583Z","0.0.12":"2026-03-28T11:32:54.770Z","0.0.13":"2026-05-17T15:22:55.367Z"},"bugs":{"url":"https://github.com/abdulgalimov/tg-framework/issues"},"author":{"name":"abdulgalimov"},"license":"MIT","homepage":"https://github.com/abdulgalimov/tg-framework#readme","keywords":["telegram","bot","framework","typescript","grammyjs"],"repository":{"type":"git","url":"git+https://github.com/abdulgalimov/tg-framework.git"},"description":"TypeScript framework for building Telegram bots","maintainers":[{"name":"abdulgalimov","email":"abdulgalimov@gmail.com"}],"readme":"# @abdulgalimov/telegram\n\nTypeScript framework for building Telegram bots.\n\n[![Node.js](https://img.shields.io/badge/Node.js-%3E%3D18-green)](https://nodejs.org/)\n[![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)](https://www.typescriptlang.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\n## Features\n\n- **Type-safe action tree routing** — hierarchical action tree with full TypeScript inference\n- **Compact payload encoding** — schema-based callback_data encoding with automatic DB fallback for payloads >64 chars\n- **Multi-step forms** — state machine with KV storage, auto-cleanup of messages, cancel button\n- **Inline keyboard builders** — confirm menus, pagination, radio/checkbox switch buttons\n- **AsyncLocalStorage context isolation** — each request runs in its own isolated context\n- **Locale / i18n support** — key=value locale files with TextBuilder for HTML messages\n- **Long polling / Webhook** — built-in long polling or webhook integration via Express\n- **Middleware pipeline** — user creation, action resolution, form handling\n- **Rate limiting** — built-in queue with global, per-chat, and group rate limit control, automatic 429 retry\n- **Zero runtime dependencies**\n\n## Installation\n\n```bash\nnpm install @abdulgalimov/telegram\n```\n\n### Peer Dependencies\n\n```bash\nnpm install @grammyjs/types\n```\n\n## Quick Start\n\n**1. Create locale files** — `locales/en.txt`, `locales/ru.txt`:\n\n```\n# locales/en.txt\nwelcome=Hello, ${name}!\nhide-button=Hide\ncancel-button=Cancel\nback-button=Back\nrefresh-button=Refresh\n```\n\n**2. Create config** — `telegram.config.js` in project root:\n\n```javascript\nexport default {\n  localesDir: 'locales',\n  defaultLocale: 'en',\n  outputDir: 'locales/generated',\n};\n```\n\n**3. Generate locale types:**\n\n```bash\nnpx telegram-prepare\n```\n\nThis creates `locales/generated/locale-types.ts` with a fully typed `LocaleKeysType`.\n\n**4. Define action tree and types:**\n\n```typescript\nimport { readFileSync } from 'node:fs';\nimport {\n  Telegram,\n  redirectAction,\n  payloadSchema,\n  type InitType,\n  type TgUser,\n} from '@abdulgalimov/telegram';\nimport type { LocaleKeysType } from './locales/generated/locale-types';\n\nconst actionsTree = {\n  core: {\n    none: {},\n    hide: {},\n    command: { '@payloads': payloadSchema.object({ command: payloadSchema.string(), value: payloadSchema.string().optional() }) },\n    text: {},\n    inline: { '@payloads': payloadSchema.object({ query: payloadSchema.string() }), select: { '@payloads': payloadSchema.object({ query: payloadSchema.string() }) } },\n    viaBot: {},\n    keyboard: { button: { '@payloads': payloadSchema.object({ label: payloadSchema.string().optional() }) } },\n  },\n  // Custom actions\n  menu: {},\n  settings: {\n    '@payloads': payloadSchema.object({ page: payloadSchema.number().optional() }),\n  },\n};\n\ntype MyUser = TgUser & { name: string };\ntype MyTree = typeof actionsTree;\ntype MyInit = InitType & { user: MyUser; locale: LocaleKeysType; tree: MyTree };\n\n// 5. Create Telegram instance\nconst tg = new Telegram<MyInit>({\n  config: {\n    apiUrl: 'https://api.telegram.org',\n    token: process.env.BOT_TOKEN!,\n    debug: {\n      payloadDecoderLevel: 'error',\n      telegramCallServiceLevel: 'error',\n      telegramUpdateLevel: 'error',\n    },\n  },\n  actionsTree,\n  loggerFactory: myLoggerFactory,\n});\n\n// 6. Create services (connect store, kv, locale)\ntg.create({\n  store: myStore,\n  kv: myKvStore,\n  locale: {\n    defaultLocale: 'en',\n    locales: [\n      { code: 'en', text: readFileSync('locales/en.txt', 'utf-8') },\n      { code: 'ru', text: readFileSync('locales/ru.txt', 'utf-8') },\n    ],\n  },\n});\n\n// 7. Register handlers\ntg.handlers.action(tg.actions.tree.core.command, async (ctx) => {\n  const { payload } = ctx;\n  const { command } = payload; // automatically typed\n  switch (command) {\n    case '/start':\n      await tg.request.reply({ text: `Welcome, ${ctx.user.name}!`, parse_mode: 'HTML' });\n      break;\n  }\n});\n\ntg.handlers.action(tg.actions.tree.menu, async (ctx) => {\n  await tg.request.reply({ text: 'Main menu' });\n});\n\ntg.handlers.action(tg.actions.tree.settings, async (ctx) => {\n  const { page } = ctx.payload; // automatically typed\n  await tg.request.reply({ text: `Settings page ${page || 1}` });\n});\n\n// 8. Initialize\nawait tg.init();\n\n// 9. Start long polling\ntg.update.startLongpoll();\n```\n\nOr use a **webhook** instead of long polling:\n\n```typescript\n// 8. Initialize\nawait tg.init();\n\n// 9. Start webhook via Express\nimport express from 'express';\n\nconst app = express();\napp.use(express.json());\n\napp.post('/webhook', (req, res) => {\n  tg.update.execute(req.body);\n  res.sendStatus(200);\n});\n\napp.listen(3000);\n```\n\n## Core Concepts\n\n### Action Tree\n\nThe action tree is a hierarchical structure that defines all routes in your bot. Every tree must include core actions:\n\n```typescript\nconst actionsTree = {\n  core: {\n    none: {},       // No-op / default action\n    hide: {},       // Hide message\n    command: {},    // Slash commands (/start, /help)\n    text: {},       // Free text input\n    inline: {       // Inline queries\n      select: {},   // Inline result selection\n    },\n    viaBot: {},     // Messages sent via bot\n    keyboard: {     // Reply keyboard\n      button: {},   // Reply keyboard button press\n    },\n  },\n  // Your custom actions:\n  wallet: {\n    send: {\n      '@payloads': payloadSchema.object({\n        tokenAddress: payloadSchema.string(),\n        amount: payloadSchema.number().optional(),\n      }),\n      confirm: {},\n      reject: {},\n    },\n  },\n};\n```\n\nActions are resolved automatically from updates: commands map to `core.command`, callback queries are decoded by payload, text messages go to `core.text` (or active form), and inline queries go to `core.inline`.\n\n### Handlers\n\nRegister handlers for specific actions using `tg.handlers.action()`. The callback receives a fully typed context — `ctx.payload` is automatically inferred from the action's `@payloads` schema:\n\n```typescript\ntg.handlers.action(tg.actions.tree.core.command, async (ctx) => {\n  const { command } = ctx.payload; // typed as string\n  if (command === '/start') {\n    await tg.request.reply({ text: 'Welcome!' });\n  }\n});\n```\n\nUse `tg.handlers.middleware()` to register middleware that runs before all child action handlers:\n\n```typescript\n// Runs before wallet.send, wallet.send.confirm, etc.\ntg.handlers.middleware(tg.actions.tree.wallet, async (ctx) => {\n  // common logic for all wallet actions\n});\n\ntg.handlers.action(tg.actions.tree.wallet.send, async (ctx) => {\n  const { tokenAddress, amount } = ctx.payload;\n  // ...\n});\n```\n\n#### Middleware — Real-World Example\n\nMiddleware is useful for loading shared data. For example, all wallet actions (`wallet.editName`, `wallet.delete`) need the wallet object — you can load it once in a middleware on `wallet` and pass it via `ctx.extra`:\n\n```typescript\n// Action tree\nconst actionsTree = {\n  core: { /* ... */ },\n  wallet: {\n    '@payloads': payloadSchema.object({\n      walletId: payloadSchema.string(),\n    }),\n    editName: {},\n    delete: {},\n  },\n};\n\n// Extra type for wallet actions\ntype WalletExtra = {\n  wallet: { id: string; name: string; balance: number };\n};\n\n// Middleware: loads wallet for all wallet.* actions\ntg.handlers.middleware<{\n    action: typeof tg.actions.tree.wallet;\n    extra: WalletExtra;\n}>(tg.actions.tree.wallet, async (ctx) => {\n  const { walletId } = ctx.payload;\n  const wallet = await db.wallets.findById(walletId);\n  if (!wallet) {\n    await tg.request.showAlert('Wallet not found');\n    return {\n      stop: true\n    }\n  }\n  ctx.extra = { wallet };\n});\n\n// Handler: uses the loaded wallet\ntg.handlers.action<{\n    action: typeof tg.actions.tree.wallet.delete;\n    extra: WalletExtra;\n}>(tg.actions.tree.wallet.delete, async (ctx) => {\n  const { wallet } = ctx.extra;\n  await db.wallets.delete(wallet.id);\n  await tg.request.reply({ text: `Wallet \"${wallet.name}\" deleted` });\n});\n\n// Handler: rename also uses wallet from middleware\ntg.handlers.action<{\n    action: typeof tg.actions.tree.wallet.editName;\n    extra: WalletExtra;\n}>(tg.actions.tree.wallet.editName, async (ctx) => {\n  const { wallet } = ctx.extra;\n  await tg.request.reply({ text: `Current name: ${wallet.name}\\nEnter new name:` });\n});\n```\n\nHandlers can return `void` (request completes) or a redirect to chain actions:\n\n```typescript\ntg.handlers.action(tg.actions.tree.core.command, async (ctx) => {\n  if (ctx.payload.command === '/start') {\n    return { redirect: redirectAction({ action: tg.actions.tree.menu }) };\n  }\n});\n```\n\n### Payload System\n\nPayloads encode typed parameters into Telegram's `callback_data` (max 64 bytes). Available schema types:\n\n```typescript\nimport { payloadSchema } from '@abdulgalimov/telegram';\n\npayloadSchema.string()    // string values\npayloadSchema.number()    // numeric values\npayloadSchema.bigint()    // bigint values\npayloadSchema.boolean()   // boolean values\npayloadSchema.enum(['a', 'b', 'c'])  // enum (string or number)\npayloadSchema.object({ key: payloadSchema.string() })  // composite object\n\n// Any schema supports .optional()\npayloadSchema.number().optional()\n```\n\nAttach a payload schema to an action using the `@payloads` key:\n\n```typescript\nconst action = {\n  '@payloads': payloadSchema.object({\n    page: payloadSchema.number(),\n    filter: payloadSchema.string().optional(),\n  }),\n};\n```\n\nEncoding format: `v1_salt_actionId_key1_value1_key2_value2`. If the encoded payload exceeds 64 characters, it is automatically stored in the database and replaced with `db_[UUID]`.\n\nUse `tg.payload.configureShorts()` to define abbreviations for frequently used payload values.\n\n### Context\n\nEach request runs inside an `AsyncLocalStorage` context. Access it via:\n\n```typescript\nconst ctx = tg.context.get();\n\nctx.action;   // Current resolved action\nctx.payload;  // Decoded payload (typed by action's @payloads schema)\nctx.user;     // Current user (your TgUser extension)\nctx.update;   // Raw Telegram Update object\nctx.form;     // Active form (if any)\nctx.flags;    // Request flags (callbackAnswered, messageDeleted, etc.)\nctx.from;     // Telegram User object from the update\nctx.inline;   // Inline query data\n```\n\n**Typed payload access:** When using `tg.handlers.action()`, the context is automatically typed based on the action's `@payloads` schema — no manual casting needed:\n\n```typescript\ntg.handlers.action(tg.actions.tree.settings, async (ctx) => {\n  const { page } = ctx.payload; // page is typed as number | undefined\n});\n```\n\n### Request Service\n\nSend messages and interact with the Telegram API:\n\n```typescript\n// Reply (edits callback message or sends new)\nawait tg.request.reply({\n  text: 'Hello!',\n  parse_mode: 'HTML',\n  reply_markup: { inline_keyboard: [[{ text: 'Click', callback_data: '...' }]] },\n});\n\n// Reply with options\nawait tg.request.reply(\n  { text: 'New message' },\n  { sendMode: true, tryReplyMessage: true },\n);\n\n// Send a photo\nawait tg.request.sendPhoto({ photo: 'https://example.com/image.jpg', caption: 'Photo' });\n\n// Delete messages\nawait tg.request.delete();             // delete current message\nawait tg.request.delete(messageId);    // delete specific message\nawait tg.request.delete([id1, id2]);   // delete multiple messages\n\n// Answer callback query\nawait tg.request.answerCallbackQuery({ text: 'Done!' });\n\n// Show alert popup\nawait tg.request.showAlert('Are you sure?');\n\n// Redirect callback to URL\nawait tg.request.redirectCallback('https://example.com');\n\n// Answer inline query\nawait tg.request.answerInlineQuery({ results: [...] });\n```\n\n### Keyboards\n\n#### Inline Keyboards\n\n```typescript\n// Confirm menu (Yes/No)\nawait tg.inlineKeyboard.confirmMenu({\n  action: tree.wallet.send,  // must have .confirm and .reject\n  text: 'Send 1 ETH?',\n  yesLabel: 'Yes',\n  noLabel: 'No',\n});\n\n// Pagination buttons\nconst buttons = tg.inlineKeyboard.pagingButtons({\n  action: tree.settings,  // must have { page?: number } payload\n  currentPage: 3,\n  totalPages: 10,\n});\n\n// Switch (radio) buttons\nconst rows = tg.inlineKeyboard.switchButtons({\n  action: tree.settings,\n  mode: SwitchButtonMode.Radio,\n  maxOnLine: 3,\n  callbackField: 'filter',\n  currentValue: 'all',\n  buttons: [\n    { label: 'All', payload: { filter: 'all' } },\n    { label: 'Active', payload: { filter: 'active' } },\n  ],\n});\n\n// Back button\nconst back = tg.inlineKeyboard.backButton({ actionItem: tree.menu });\n\n// Refresh button (re-encodes current action)\nconst refresh = tg.inlineKeyboard.refreshButton();\n```\n\n### Forms\n\nMulti-step forms with state stored in KV:\n\n```typescript\n// Define a form action in the tree\nconst actionsTree = {\n  // ...\n  createWallet: {\n    progress: {},   // Required: handles each form step\n    cancel: {},     // Optional: cancel button action\n  },\n};\n\n// Start a form\ntg.handlers.action(tg.actions.tree.createWallet, async (ctx) => {\n  await tg.form.create({\n    action: tg.actions.tree.createWallet,\n    defaultData: { step: 1, name: '' },\n  });\n  await tg.form.reply({ text: 'Enter wallet name:' });\n});\n\n// Process form input\ntg.handlers.action(tg.actions.tree.createWallet.progress, async (ctx) => {\n  const { form } = ctx;\n  form.data.name = ctx.update.message?.text;\n  form.data.step = 2;\n  await tg.form.save(form);\n});\n\n// Cancel form\ntg.handlers.action(tg.actions.tree.createWallet.cancel, async (ctx) => {\n  await tg.form.delete();\n  return { redirect: redirectAction({ action: tg.actions.tree.menu }) };\n});\n```\n\nForm features:\n- State persisted in KV as `user_form_{userId}`\n- Auto-deletes user messages during form flow\n- Automatically adds a cancel button (using locale key `cancel-button`)\n- `form.reply()` — sends/edits form prompt\n- `form.send()` — sends additional message tracked in form history\n\n### Locale / i18n\n\nLocale types are **auto-generated** from `.txt` files. You never define them manually.\n\n**1. Create locale files** in `key=value` format with `${arg}` interpolation:\n\n```\n# locales/en.txt\nwelcome=Hello, ${name}!\nbalance=Balance: ${amount}\nhide-button=Hide\ncancel-button=Cancel\nback-button=Back\nrefresh-button=Refresh\n```\n\n```\n# locales/ru.txt\nwelcome=Привет, ${name}!\nbalance=Баланс: ${amount}\nhide-button=Скрыть\ncancel-button=Отмена\nback-button=Назад\nrefresh-button=Обновить\n```\n\n**2. Create `telegram.config.js`** in project root:\n\n```javascript\nexport default {\n  localesDir: 'locales',\n  defaultLocale: 'en',\n  outputDir: 'locales/generated',\n};\n```\n\n**3. Run code generation** before building your app:\n\n```bash\nnpx telegram-prepare\n```\n\nThis reads the default locale file, parses all keys and `${arg}` placeholders, and generates `locales/generated/locale-types.ts`:\n\n```typescript\n// This file is auto-generated by tg-framework. Do not edit manually.\n\ntype ArgValue = string | number;\n\nexport type LocaleKeysType = {\n  \"welcome\": { text: \"Hello, ${name}!\"; args: { name: ArgValue } };\n  \"balance\": { text: \"Balance: ${amount}\"; args: { amount: ArgValue } };\n  \"hide-button\": { text: \"Hide\"; args: undefined };\n  \"cancel-button\": { text: \"Cancel\"; args: undefined };\n  \"back-button\": { text: \"Back\"; args: undefined };\n  \"refresh-button\": { text: \"Refresh\"; args: undefined };\n};\n```\n\n**4. Import and use** — the generated type plugs into `InitType`:\n\n```typescript\nimport type { LocaleKeysType } from './locales/generated/locale-types';\n\ntype MyInit = InitType & { user: MyUser; locale: LocaleKeysType; tree: MyTree };\n```\n\n**5. Pass locale data at runtime** — read `.txt` files and pass their content:\n\n```typescript\nimport { readFileSync } from 'node:fs';\n\ntg.create({\n  // ...\n  locale: {\n    defaultLocale: 'en',\n    locales: [\n      { code: 'en', text: readFileSync('locales/en.txt', 'utf-8') },\n      { code: 'ru', text: readFileSync('locales/ru.txt', 'utf-8') },\n    ],\n  },\n});\n```\n\n**6. Use in handler** — fully type-safe:\n\n```typescript\n// Get localized text (key and args are type-checked)\nconst text = tg.locale.text('welcome', { args: { name: 'Alice' } });\n\n// TextBuilder — fluent API for HTML messages\nconst message = tg.locale.build()\n  .addLocale('welcome', { args: { name: 'Alice' } })\n  .break()\n  .addText('Your balance:', { bold: true })\n  .appendText(' 100 USDT', { code: true })\n  .addSection()\n  .addText('Choose an option:')\n  .toString();\n```\n\nRequired locale keys: `hide-button`, `cancel-button`, `back-button`, `refresh-button`.\n\n> **Tip:** Add `npx telegram-prepare` to your build script (e.g. `\"prebuild\": \"telegram-prepare\"`) so types stay in sync.\n\n### Redirect\n\nA handler can return a redirect to chain actions (max 5 redirects):\n\n```typescript\nimport { redirectAction } from '@abdulgalimov/telegram';\n\ntg.handlers.action(tg.actions.tree.core.command, async (ctx) => {\n  const { command } = ctx.payload;\n  if (command === '/start') {\n    // Redirect /start to menu\n    return { redirect: redirectAction({ action: tg.actions.tree.menu }) };\n  }\n});\n\ntg.handlers.action(tg.actions.tree.menu, async (ctx) => {\n  await tg.request.reply({ text: 'Menu' });\n});\n```\n\nRedirect with payload:\n\n```typescript\nreturn {\n  redirect: redirectAction({\n    action: tg.actions.tree.settings,\n    payload: { page: 1 },\n  }),\n};\n```\n\n## Interfaces to Implement\n\n| Interface | Purpose |\n|---|---|\n| `TelegramStore` | Database adapter: `actions`, `users`, `inlineKeyboards`, `replyKeyboards` |\n| `ActionsStore` | `createAll(paths)` — persist action paths and return IDs |\n| `UsersStore<TUser>` | `createOrUpdate(data)` — upsert user by Telegram ID |\n| `InlineKeyboardsStore` | Store/retrieve long payloads, track message contexts |\n| `ReplyKeyboardsStore` | Store/retrieve reply keyboard state per chat |\n| `KvStore` | Key-value store: `getValue`, `setValue`, `removeValue`, `expire` |\n| `TgLoggerFactory` | `create(name)` — returns `TgLogger` instance |\n| `TgLogger` | `error`, `warn`, `info`, `debug`, `setLogLevel` |\n\n`TgUser` base interface (extend with your own fields):\n\n```typescript\ninterface TgUser {\n  id: bigint;\n  telegramId: number;\n  langCode: string | null;\n}\n```\n\n## Configuration\n\n```typescript\ntype TelegramConfig = {\n  apiUrl: string;     // Telegram API URL (https://api.telegram.org)\n  token: string;      // Bot token from @BotFather\n  debug: {\n    payloadDecoderLevel: string;       // Log level for payload decoding\n    telegramCallServiceLevel: string;  // Log level for API calls\n    telegramUpdateLevel: string;       // Log level for update processing\n  };\n  throttle?: ThrottleConfig;           // Rate limiting settings (optional)\n};\n```\n\n### Rate Limiting\n\nBuilt-in request rate control for Telegram Bot API. All outgoing calls pass through a queue that respects Telegram's rate limits. Enabled by default with sensible values.\n\n```typescript\ntype ThrottleConfig = {\n  globalLimit?: number;        // Max requests per second globally (default: 30)\n  perChatInterval?: number;    // Min interval in ms between messages to same chat (default: 1000)\n  groupPerMinuteLimit?: number; // Max messages per minute for group chats (default: 20)\n  exemptMethods?: ApiMethodType[]; // Methods exempt from throttling\n};\n```\n\n**How it works:**\n\n- **Global limit** — max 30 requests per second (sliding window)\n- **Per-chat limit** — max 1 message per second to the same chat\n- **Group limit** — max 20 messages per minute for groups (chat_id < 0)\n- **429 retry** — on `Too Many Requests`, the request is automatically retried after `retry_after` (up to 3 attempts)\n\n**Exempt methods** — bypass the queue (read-only and responses to incoming requests):\n- All `answer*` methods (`answerCallbackQuery`, `answerInlineQuery`, `answerPreCheckoutQuery`, `answerShippingQuery`, `answerWebAppQuery`)\n- All `get*` methods (`getMe`, `getChat`, `getFile`, `getUpdates`, etc.)\n\n**Configuration example:**\n\n```typescript\nconst tg = new Telegram<MyInit>({\n  config: {\n    apiUrl: 'https://api.telegram.org',\n    token: process.env.BOT_TOKEN!,\n    debug: { /* ... */ },\n    // Throttle settings (all fields are optional)\n    throttle: {\n      globalLimit: 25,\n      perChatInterval: 1500,\n      groupPerMinuteLimit: 15,\n    },\n  },\n  // ...\n});\n```\n\nWithout specifying `throttle`, default Telegram limits apply. To provide custom exempt methods, pass the `exemptMethods` array (fully replaces the default list).\n\n## Update Pipeline\n\n```\nUpdate → AsyncContext → UserMw → ActionsMw → handler → redirect chain → auto-answer callback → batch delete\n```\n\n1. **Long Polling / Webhook** — receives updates via long polling (`tg.update.startLongpoll()`) or webhook (`tg.update.execute(update)`)\n2. **AsyncContext** — creates isolated AsyncLocalStorage context\n3. **UserMw** — creates or updates user in the database\n4. **ActionsMw** — resolves the action:\n   - Active form → `form.progress`\n   - Text → command (`/cmd`) | text | viaBot\n   - Callback query → decode payload → action\n   - Inline query → inline action\n5. **Handler** — your business logic\n6. **Redirect** — chains up to 5 redirects between actions\n7. **Auto-answer** — automatically answers unanswered callback queries\n8. **Batch delete** — deletes all messages marked for deletion during the request\n\n## Utilities\n\n### HTMLFormat\n\nStatic methods for Telegram HTML formatting:\n\n```typescript\nimport { HTMLFormat } from '@abdulgalimov/telegram';\n\nHTMLFormat.bold('text')           // <b>text</b>\nHTMLFormat.italic('text')         // <i>text</i>\nHTMLFormat.code('text')           // <code>text</code>\nHTMLFormat.pre('text')            // <pre>text</pre>\nHTMLFormat.strike('text')         // <s>text</s>\nHTMLFormat.spoiler('text')        // <spoiler>text</spoiler>\nHTMLFormat.blockquote('text')     // <blockquote>text</blockquote>\nHTMLFormat.link('text', 'url')    // <a href=\"url\">text</a>\nHTMLFormat.encode('a < b')        // escapes HTML entities\n```\n\n### TextBuilder\n\nFluent API for building HTML messages (see [Locale / i18n](#locale--i18n)):\n\n```typescript\nconst text = tg.locale.build()\n  .addLocale('key')                  // add localized line\n  .addText('raw text')               // add raw text line\n  .appendText(' suffix')             // append to last line\n  .appendText('value', { bold: true })  // append with formatting\n  .appendButton('Click', 'https://...')  // append link\n  .addSection()                      // add separator line\n  .break()                           // add empty line\n  .toString();\n```\n\n## Template\n\nFor a production-ready example, see the template bot:\n\n**[telegram-bot-template](https://github.com/abdulgalimov/telegram-bot-template)**\n\n## License\n\nMIT\n","readmeFilename":"README.md"}