{"_id":"@bonkers-agency/grammy-test","_rev":"4-305013ae8ba5485881f5a7f2a94a7c94","name":"@bonkers-agency/grammy-test","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.0":{"name":"@bonkers-agency/grammy-test","version":"0.1.0","keywords":["grammy","telegram","bot","testing","test","mock","unit-test","integration-test","bun","deno"],"author":{"name":"BONKERS Agency"},"license":"MIT","_id":"@bonkers-agency/grammy-test@0.1.0","maintainers":[{"name":"metaxona","email":"metaxonadev@gmail.com"}],"homepage":"https://github.com/BONKERS-agency/grammy-test#readme","bugs":{"url":"https://github.com/BONKERS-agency/grammy-test/issues"},"dist":{"shasum":"00253d206a872abf8e5730c8bac55333908cb857","tarball":"https://registry.npmjs.org/@bonkers-agency/grammy-test/-/grammy-test-0.1.0.tgz","fileCount":79,"integrity":"sha512-iI+Mp6trNzkdpYXURX5EIywbDBUP+ovZ9ACxkqgkCAyyL30CAWUNgkvQUE4VuYzo2jxSnCJMeLJdSJzaCWdSYQ==","signatures":[{"sig":"MEUCIQDHN+PEZh1WvurxZoOsSDv/3QpUMtdtHvCk0bcHzU8XGAIgVVRZ5Ma/DoxWSbE5e7pIFNjiaCLgSFRNn3z39imxNWo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":654370},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"bun":"./dist/index.js","deno":"./dist/index.js","types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"904152d5f86568a126b5f5931172d25bef91f2b6","scripts":{"dev":"tsc --watch","test":"vitest","build":"tsc","clean":"rm -rf dist","test:bun":"bun run vitest run","test:run":"vitest run","typecheck":"tsc --noEmit","prepublishOnly":"npm run clean && npm run build && npm run test:run"},"_npmUser":{"name":"metaxona","email":"metaxonadev@gmail.com"},"repository":{"url":"git+https://github.com/BONKERS-agency/grammy-test.git","type":"git"},"_npmVersion":"11.7.0","description":"Testing framework for grammY Telegram bots - simulate Telegram interactions without API calls","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"devDependencies":{"grammy":"^1.38.0","vitest":"^2.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","@grammyjs/runner":"^2.0.3","@grammyjs/conversations":"^2.1.1"},"peerDependencies":{"grammy":">=1.38.0 <2","@grammyjs/runner":">=2.0.0","@grammyjs/conversations":">=2.0.0"},"peerDependenciesMeta":{"@grammyjs/runner":{"optional":true},"@grammyjs/conversations":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/grammy-test_0.1.0_1770139415014_0.2787631084864124","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bonkers-agency/grammy-test","version":"0.1.1","keywords":["grammy","telegram","bot","testing","test","mock","unit-test","integration-test","bun","deno"],"author":{"name":"BONKERS Agency"},"license":"MIT","_id":"@bonkers-agency/grammy-test@0.1.1","maintainers":[{"name":"metaxona","email":"metaxonadev@gmail.com"}],"homepage":"https://github.com/BONKERS-agency/grammy-test#readme","bugs":{"url":"https://github.com/BONKERS-agency/grammy-test/issues"},"dist":{"shasum":"bb36c76a4f8260e63b17da296d8d7bb7c2bf1ff5","tarball":"https://registry.npmjs.org/@bonkers-agency/grammy-test/-/grammy-test-0.1.1.tgz","fileCount":79,"integrity":"sha512-lAuHiJl1HaEMiDNfjw8XpvylAkcyIOo0/qQdgdkhGygAtoggUH+vaoph1ynoVl85YbGr2FIVs7GrNsemQ1832A==","signatures":[{"sig":"MEUCIGNrGmSZn0uYWO6SqxBS6hV/Ar48dNgI9XUQcj+4XTB1AiEAu4ume4zU9ehgDqp/8+wqz9bgvx17Q/JLg8bwuNbRBTA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":654450},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"bun":"./dist/index.js","deno":"./dist/index.js","types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"67a485a9f66ad22dc90409ddb5af465bd013d864","scripts":{"dev":"tsc --watch","test":"vitest","build":"tsc","clean":"rm -rf dist","test:bun":"bun run vitest run","test:run":"vitest run","typecheck":"tsc --noEmit","prepublishOnly":"npm run clean && npm run build && npm run test:run"},"_npmUser":{"name":"metaxona","email":"metaxonadev@gmail.com"},"repository":{"url":"git+https://github.com/BONKERS-agency/grammy-test.git","type":"git"},"_npmVersion":"11.7.0","description":"Testing framework for grammY Telegram bots - simulate Telegram interactions without API calls","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"devDependencies":{"grammy":"^1.38.0","vitest":"^2.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","@grammyjs/runner":"^2.0.3","@grammyjs/conversations":"^2.1.1"},"peerDependencies":{"grammy":">=1.38.0 <2","@grammyjs/runner":">=2.0.0","@grammyjs/conversations":">=2.0.0"},"peerDependenciesMeta":{"@grammyjs/runner":{"optional":true},"@grammyjs/conversations":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/grammy-test_0.1.1_1770139945534_0.09942231061899087","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@bonkers-agency/grammy-test","version":"0.1.2","keywords":["grammy","telegram","bot","testing","test","mock","unit-test","integration-test","bun","deno"],"author":{"name":"BONKERS Agency"},"license":"MIT","_id":"@bonkers-agency/grammy-test@0.1.2","maintainers":[{"name":"metaxona","email":"metaxonadev@gmail.com"}],"homepage":"https://github.com/BONKERS-agency/grammy-test#readme","bugs":{"url":"https://github.com/BONKERS-agency/grammy-test/issues"},"dist":{"shasum":"aa26a84d777500bba40e44a24372e8bcbdfa6b43","tarball":"https://registry.npmjs.org/@bonkers-agency/grammy-test/-/grammy-test-0.1.2.tgz","fileCount":95,"integrity":"sha512-fthJYcqgZXyCBPTsqTLhJmf//sZ3MJlFZmaqIEqb1Cbfk76VrNBAGDR6yXSwuNnNVYr0AOHb+G4ZNhUiJtIsYw==","signatures":[{"sig":"MEUCIG9DPP6cZ5RGteHqJf/tqZwzLfKsYZaMKvU/OeCcxdCTAiEAwhOZe6M4ZvPC16OtoAeZuwCv0P+jifNg9kPiVPoERKw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":760051},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"bun":"./dist/index.js","deno":"./dist/index.js","types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"eac0c4d765c64c02cb7d6ce6a579f237b896a6b0","scripts":{"dev":"tsc --watch","lint":"biome check .","test":"vitest","build":"tsc","clean":"rm -rf dist","format":"biome format --write .","lint:fix":"biome check --write .","test:bun":"bun run vitest run","test:run":"vitest run","typecheck":"tsc --noEmit","prepublishOnly":"npm run clean && npm run build && npm run lint && npm run test:run"},"_npmUser":{"name":"metaxona","email":"metaxonadev@gmail.com"},"repository":{"url":"git+https://github.com/BONKERS-agency/grammy-test.git","type":"git"},"_npmVersion":"11.7.0","description":"Testing framework for grammY Telegram bots - simulate Telegram interactions without API calls","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"devDependencies":{"grammy":"^1.38.0","vitest":"^2.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","@biomejs/biome":"^2.3.14","@grammyjs/runner":"^2.0.3","@grammyjs/conversations":"^2.1.1"},"peerDependencies":{"grammy":">=1.38.0 <2","@grammyjs/runner":">=2.0.0","@grammyjs/conversations":">=2.0.0"},"peerDependenciesMeta":{"@grammyjs/runner":{"optional":true},"@grammyjs/conversations":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/grammy-test_0.1.2_1770167821565_0.8267848131548241","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@bonkers-agency/grammy-test","version":"0.1.3","description":"Testing framework for grammY Telegram bots - simulate Telegram interactions without API calls","main":"dist/index.js","module":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","bun":"./dist/index.js","deno":"./dist/index.js","import":"./dist/index.js","default":"./dist/index.js"}},"sideEffects":false,"scripts":{"build":"tsc","clean":"rm -rf dist","dev":"tsc --watch","typecheck":"tsc --noEmit","test":"vitest","test:run":"vitest run","test:bun":"bun run vitest run","lint":"biome check .","lint:fix":"biome check --write .","format":"biome format --write .","prepublishOnly":"npm run clean && npm run build && npm run lint && npm run test:run"},"keywords":["grammy","telegram","bot","testing","test","mock","unit-test","integration-test","bun","deno"],"author":{"name":"BONKERS Agency"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/BONKERS-agency/grammy-test.git"},"bugs":{"url":"https://github.com/BONKERS-agency/grammy-test/issues"},"homepage":"https://github.com/BONKERS-agency/grammy-test#readme","type":"module","engines":{"node":">=18.0.0"},"peerDependencies":{"@grammyjs/conversations":">=2.0.0","@grammyjs/runner":">=2.0.0","grammy":">=1.38.0 <2"},"peerDependenciesMeta":{"@grammyjs/conversations":{"optional":true},"@grammyjs/runner":{"optional":true}},"devDependencies":{"@biomejs/biome":"^2.3.14","@grammyjs/conversations":"^2.1.1","@grammyjs/runner":"^2.0.3","@types/node":"^20.0.0","grammy":"^1.38.0","typescript":"^5.0.0","vitest":"^2.0.0"},"gitHead":"05a404ee463b8ae9e1bdf864e9834c66ac4bcd3b","_id":"@bonkers-agency/grammy-test@0.1.3","_nodeVersion":"20.19.5","_npmVersion":"11.7.0","dist":{"integrity":"sha512-1yarA/3y5LNpzA0icPLHh2f5Pr4ITgb+youDrLAovlhj9wcH7MLK63q0nheyBwoxx84AZKH9lsMTxuNV+fXThw==","shasum":"a511ff2de6e89c10cfee2e3a96ab340b3806dd39","tarball":"https://registry.npmjs.org/@bonkers-agency/grammy-test/-/grammy-test-0.1.3.tgz","fileCount":95,"unpackedSize":762529,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDtAci52bYyo2pmMGNMv9FIMxJQskBRGZ4+IAta4x04FgIhAP7HqwOhpRSnJWf3f8u5yxWeCJWXdia+6yFeh0/zFm4P"}]},"_npmUser":{"name":"metaxona","email":"metaxonadev@gmail.com"},"directories":{},"maintainers":[{"name":"metaxona","email":"metaxonadev@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/grammy-test_0.1.3_1770179344529_0.6987992410631099"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-03T17:23:34.943Z","modified":"2026-02-04T04:29:05.104Z","0.1.0":"2026-02-03T17:23:35.231Z","0.1.1":"2026-02-03T17:32:25.727Z","0.1.2":"2026-02-04T01:17:01.742Z","0.1.3":"2026-02-04T04:29:04.691Z"},"bugs":{"url":"https://github.com/BONKERS-agency/grammy-test/issues"},"author":{"name":"BONKERS Agency"},"license":"MIT","homepage":"https://github.com/BONKERS-agency/grammy-test#readme","keywords":["grammy","telegram","bot","testing","test","mock","unit-test","integration-test","bun","deno"],"repository":{"type":"git","url":"git+https://github.com/BONKERS-agency/grammy-test.git"},"description":"Testing framework for grammY Telegram bots - simulate Telegram interactions without API calls","maintainers":[{"name":"metaxona","email":"metaxonadev@gmail.com"}],"readme":"# grammy-test\n\nTesting framework for [grammY](https://grammy.dev/) Telegram bots - simulate Telegram interactions without making API calls.\n\n[![npm version](https://img.shields.io/npm/v/@bonkers-agency/grammy-test.svg)](https://www.npmjs.com/package/@bonkers-agency/grammy-test)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## Features\n\n- **Zero Network Calls** - All Telegram API interactions are simulated in-memory\n- **Realistic Simulation** - Stateful server with proper validation and error handling\n- **Full grammY Support** - Works with commands, callbacks, conversations, inline queries, and more\n- **Bot Permission Enforcement** - Simulates Telegram's admin permission system\n- **Type-Safe** - Full TypeScript support matching grammY types\n- **Test Runner Agnostic** - Works with Vitest, Jest, Mocha, or any test framework\n- **Multi-Runtime** - Supports Node.js 18+, Bun, and Deno\n\n## Installation\n\n```bash\nnpm install @bonkers-agency/grammy-test --save-dev\n```\n\n## Quick Start\n\n```typescript\nimport { describe, it, expect, beforeEach, afterEach } from \"vitest\";\nimport { TestBot } from \"@bonkers-agency/grammy-test\";\n\ndescribe(\"MyBot\", () => {\n  let testBot: TestBot;\n\n  beforeEach(() => {\n    testBot = new TestBot();\n    testBot.command(\"start\", (ctx) => ctx.reply(\"Hello!\"));\n  });\n\n  afterEach(() => {\n    testBot.dispose(); // Always clean up!\n  });\n\n  it(\"responds to /start\", async () => {\n    const user = testBot.createUser({ first_name: \"Alice\" });\n    const chat = testBot.createChat({ type: \"private\" });\n\n    const response = await testBot.sendCommand(user, chat, \"/start\");\n\n    expect(response.text).toBe(\"Hello!\");\n  });\n});\n```\n\n## Testing Admin Commands\n\nThe framework enforces bot permissions like real Telegram:\n\n```typescript\nit(\"bans a user\", async () => {\n  const admin = testBot.createUser({ first_name: \"Admin\" });\n  const target = testBot.createUser({ first_name: \"Target\" });\n  const group = testBot.createChat({ type: \"supergroup\", title: \"Test\" });\n\n  testBot.setOwner(group, admin);\n  testBot.setMember(group, target);\n  // Bot needs permission to ban users\n  testBot.setBotAdmin(group, { can_restrict_members: true });\n\n  testBot.command(\"ban\", async (ctx) => {\n    await ctx.banChatMember(target.id);\n    await ctx.reply(\"Banned!\");\n  });\n\n  const response = await testBot.sendCommand(admin, group, \"/ban\");\n  expect(response.text).toBe(\"Banned!\");\n});\n```\n\n## Testing Conversations\n\n```typescript\nimport { session } from \"grammy\";\nimport { conversations, createConversation } from \"@grammyjs/conversations\";\nimport { createConversationTester } from \"@bonkers-agency/grammy-test\";\n\n// Set up bot with conversations\ntestBot.use(session({ initial: () => ({}) }));\ntestBot.use(conversations());\ntestBot.use(createConversation(myConversation));\n\n// Test multi-step flow\nconst convo = createConversationTester(testBot, user, chat);\nconst r1 = await convo.start(\"/survey\");\nexpect(r1.text).toBe(\"What's your name?\");\n\nconst r2 = await convo.say(\"Alice\");\nexpect(r2.text).toBe(\"Nice to meet you, Alice!\");\n```\n\n## BotResponse Object\n\nEvery simulation returns a rich response object:\n\n```typescript\nconst response = await testBot.sendCommand(user, chat, \"/menu\");\n\nresponse.text;              // Last message text\nresponse.texts;             // All message texts\nresponse.messages;          // Full Message objects\nresponse.keyboard?.inline;  // Inline keyboard buttons\nresponse.keyboard?.reply;   // Reply keyboard buttons\nresponse.callbackAnswer;    // Callback query answer\nresponse.poll;              // Poll object\nresponse.invoice;           // Invoice object\nresponse.error;             // API error if any\n```\n\n## Bot Permission Reference\n\n```typescript\n// Ban, kick, mute, restrict, slow mode\ntestBot.setBotAdmin(group, { can_restrict_members: true });\n\n// Promote, demote, set admin title\ntestBot.setBotAdmin(group, { can_promote_members: true });\n\n// Pin, unpin messages\ntestBot.setBotAdmin(group, { can_pin_messages: true });\n\n// Delete other users' messages\ntestBot.setBotAdmin(group, { can_delete_messages: true });\n\n// Invite links, approve/decline join requests\ntestBot.setBotAdmin(group, { can_invite_users: true });\n\n// Forum topics\ntestBot.setBotAdmin(forum, { can_manage_topics: true });\n\n// Change chat title, photo, description\ntestBot.setBotAdmin(group, { can_change_info: true });\n```\n\n## Supported Features\n\n- Messages (text, media, replies, edits, deletions)\n- Commands with arguments\n- Inline & reply keyboards\n- Callback queries\n- Inline queries\n- Conversations (@grammyjs/conversations)\n- Polls & quizzes\n- Payments (invoices, pre-checkout, successful payment)\n- Forum topics\n- Invite links & join requests\n- Message reactions\n- File handling (photos, documents, audio, video)\n- Markdown/HTML parsing to entities\n- Webhook simulation (Express, Hono, Fastify, etc.)\n\n## Documentation\n\n- [Overview](./docs/overview.md) - Features and how it works\n- [Usage Guide](./docs/usage.md) - Detailed examples\n- [Architecture](./docs/architecture.md) - Internal design\n\n## Runtime Support\n\n| Runtime | Status |\n|---------|--------|\n| Node.js 18+ | Full support |\n| Bun | Full support |\n| Deno | Works via `npm:` specifier |\n\n## License\n\nMIT\n","readmeFilename":"README.md"}