grammy 1.9.2 β†’ 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -151,7 +151,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
151
151
  <td align="center"><a href="https://github.com/jokasimr"><img src="https://avatars.githubusercontent.com/u/20954731?v=4?s=100" width="100px;" alt=""/><br /><sub><b>jokasimr</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Ajokasimr" title="Bug reports">πŸ›</a></td>
152
152
  <td align="center"><a href="https://github.com/CikiMomogi"><img src="https://avatars.githubusercontent.com/u/74030149?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ciki Momogi</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=CikiMomogi" title="Documentation">πŸ“–</a></td>
153
153
  <td align="center"><a href="https://github.com/AndreoliBR"><img src="https://avatars.githubusercontent.com/u/15970011?v=4?s=100" width="100px;" alt=""/><br /><sub><b>AndreoliBR</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3AAndreoliBR" title="Reviewed Pull Requests">πŸ‘€</a></td>
154
- <td align="center"><a href="https://github.com/Loskir"><img src="https://avatars.githubusercontent.com/u/21295738?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kirill Loskutov</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=Loskir" title="Documentation">πŸ“–</a> <a href="https://github.com/grammyjs/grammY/issues?q=author%3ALoskir" title="Bug reports">πŸ›</a> <a href="#ideas-Loskir" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="#design-Loskir" title="Design">🎨</a> <a href="#question-Loskir" title="Answering Questions">πŸ’¬</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3ALoskir" title="Reviewed Pull Requests">πŸ‘€</a></td>
154
+ <td align="center"><a href="https://github.com/Loskir"><img src="https://avatars.githubusercontent.com/u/21295738?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kirill Loskutov</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=Loskir" title="Documentation">πŸ“–</a> <a href="https://github.com/grammyjs/grammY/issues?q=author%3ALoskir" title="Bug reports">πŸ›</a> <a href="#ideas-Loskir" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="#design-Loskir" title="Design">🎨</a> <a href="#question-Loskir" title="Answering Questions">πŸ’¬</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3ALoskir" title="Reviewed Pull Requests">πŸ‘€</a> <a href="https://github.com/grammyjs/grammY/commits?author=Loskir" title="Code">πŸ’»</a> <a href="#plugin-Loskir" title="Plugin/utility libraries">πŸ”Œ</a></td>
155
155
  </tr>
156
156
  <tr>
157
157
  <td align="center"><a href="https://lungers.com/"><img src="https://avatars.githubusercontent.com/u/32808683?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrew Lane</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3AAndrewLaneX" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3AAndrewLaneX" title="Reviewed Pull Requests">πŸ‘€</a></td>
@@ -178,13 +178,13 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
178
178
  <td align="center"><a href="https://zhemu.buzz/"><img src="https://avatars.githubusercontent.com/u/56839018?v=4?s=100" width="100px;" alt=""/><br /><sub><b>linbuxiao</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=linbuxiao" title="Documentation">πŸ“–</a> <a href="#translation-linbuxiao" title="Translation">🌍</a></td>
179
179
  <td align="center"><a href="https://github.com/JiquanWang99"><img src="https://avatars.githubusercontent.com/u/63894579?v=4?s=100" width="100px;" alt=""/><br /><sub><b>JiquanWang99</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=JiquanWang99" title="Documentation">πŸ“–</a> <a href="#translation-JiquanWang99" title="Translation">🌍</a></td>
180
180
  <td align="center"><a href="http://bor691.ir/"><img src="https://avatars.githubusercontent.com/u/4184939?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Borhan Hafez</b></sub></a><br /><a href="#plugin-zumoshi" title="Plugin/utility libraries">πŸ”Œ</a></td>
181
- <td align="center"><a href="https://blog.limx.dev/"><img src="https://avatars.githubusercontent.com/u/6434137?v=4?s=100" width="100px;" alt=""/><br /><sub><b>WingLim</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=WingLim" title="Documentation">πŸ“–</a> <a href="#translation-WingLim" title="Translation">🌍</a></td>
181
+ <td align="center"><a href="https://blog.limx.dev/"><img src="https://avatars.githubusercontent.com/u/6434137?v=4?s=100" width="100px;" alt=""/><br /><sub><b>WingLim</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=WingLim" title="Documentation">πŸ“–</a> <a href="#translation-WingLim" title="Translation">🌍</a> <a href="https://github.com/grammyjs/grammY/commits?author=WingLim" title="Code">πŸ’»</a> <a href="#plugin-WingLim" title="Plugin/utility libraries">πŸ”Œ</a> <a href="#ideas-WingLim" title="Ideas, Planning, & Feedback">πŸ€”</a></td>
182
182
  </tr>
183
183
  <tr>
184
184
  <td align="center"><a href="https://github.com/taotie111"><img src="https://avatars.githubusercontent.com/u/44166322?v=4?s=100" width="100px;" alt=""/><br /><sub><b>taotie111</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=taotie111" title="Documentation">πŸ“–</a> <a href="#translation-taotie111" title="Translation">🌍</a></td>
185
185
  <td align="center"><a href="https://www.linkedin.com/in/merlin-brandes-42328717a/"><img src="https://avatars.githubusercontent.com/u/14237330?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Merlin</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=FatalMerlin" title="Documentation">πŸ“–</a></td>
186
186
  <td align="center"><a href="https://darve.sh"><img src="https://avatars.githubusercontent.com/u/22394081?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Darvesh</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Adarvesh" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=darvesh" title="Code">πŸ’»</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Adarvesh" title="Reviewed Pull Requests">πŸ‘€</a></td>
187
- <td align="center"><a href="http://telegram.me/dcdunkan"><img src="https://avatars.githubusercontent.com/u/70066170?v=4?s=100" width="100px;" alt=""/><br /><sub><b>dcdunkan</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Adcdunkan" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=dcdunkan" title="Code">πŸ’»</a> <a href="#plugin-dcdunkan" title="Plugin/utility libraries">πŸ”Œ</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Adcdunkan" title="Reviewed Pull Requests">πŸ‘€</a> <a href="https://github.com/grammyjs/grammY/commits?author=dcdunkan" title="Documentation">πŸ“–</a> <a href="#ideas-dcdunkan" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="#infra-dcdunkan" title="Infrastructure (Hosting, Build-Tools, etc)">πŸš‡</a></td>
187
+ <td align="center"><a href="http://telegram.me/dcdunkan"><img src="https://avatars.githubusercontent.com/u/70066170?v=4?s=100" width="100px;" alt=""/><br /><sub><b>dcdunkan</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Adcdunkan" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=dcdunkan" title="Code">πŸ’»</a> <a href="#plugin-dcdunkan" title="Plugin/utility libraries">πŸ”Œ</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Adcdunkan" title="Reviewed Pull Requests">πŸ‘€</a> <a href="https://github.com/grammyjs/grammY/commits?author=dcdunkan" title="Documentation">πŸ“–</a> <a href="#ideas-dcdunkan" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="#infra-dcdunkan" title="Infrastructure (Hosting, Build-Tools, etc)">πŸš‡</a> <a href="#tool-dcdunkan" title="Tools">πŸ”§</a></td>
188
188
  <td align="center"><a href="https://xuann.wang/"><img src="https://avatars.githubusercontent.com/u/44045911?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kid</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=kidonng" title="Documentation">πŸ“–</a> <a href="#translation-kidonng" title="Translation">🌍</a></td>
189
189
  <td align="center"><a href="http://slava.fomin.io/"><img src="https://avatars.githubusercontent.com/u/1702725?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Slava Fomin II</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Aslavafomin" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=slavafomin" title="Documentation">πŸ“–</a></td>
190
190
  <td align="center"><a href="https://kikobeats.com/"><img src="https://avatars.githubusercontent.com/u/2096101?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kiko Beats</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=Kikobeats" title="Documentation">πŸ“–</a></td>
@@ -204,7 +204,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
204
204
  <td align="center"><a href="https://github.com/Scrip7"><img src="https://avatars.githubusercontent.com/u/37535505?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hesoyam</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=Scrip7" title="Documentation">πŸ“–</a></td>
205
205
  <td align="center"><a href="http://yrz.am"><img src="https://avatars.githubusercontent.com/u/96742416?v=4?s=100" width="100px;" alt=""/><br /><sub><b>yrzam</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Ayrzam" title="Bug reports">πŸ›</a></td>
206
206
  <td align="center"><a href="https://github.com/drmikecrowe"><img src="https://avatars.githubusercontent.com/u/90312?v=4?s=100" width="100px;" alt=""/><br /><sub><b>drmikecrowe</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Adrmikecrowe" title="Reviewed Pull Requests">πŸ‘€</a></td>
207
- <td align="center"><a href="https://rys.pw"><img src="https://avatars.githubusercontent.com/u/1641362?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=C0rn3j" title="Documentation">πŸ“–</a></td>
207
+ <td align="center"><a href="https://rys.pw"><img src="https://avatars.githubusercontent.com/u/1641362?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Martin</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=C0rn3j" title="Documentation">πŸ“–</a> <a href="https://github.com/grammyjs/grammY/issues?q=author%3AC0rn3j" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3AC0rn3j" title="Reviewed Pull Requests">πŸ‘€</a></td>
208
208
  <td align="center"><a href="http://pavelpolyakov.com/"><img src="https://avatars.githubusercontent.com/u/839290?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pavel</b></sub></a><br /><a href="#example-PavelPolyakov" title="Examples">πŸ’‘</a></td>
209
209
  </tr>
210
210
  <tr>
@@ -217,7 +217,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
217
217
  <td align="center"><a href="https://oott123.com"><img src="https://avatars.githubusercontent.com/u/905663?v=4?s=100" width="100px;" alt=""/><br /><sub><b>δΈ‰δΈ‰</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Aoott123" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=oott123" title="Code">πŸ’»</a></td>
218
218
  </tr>
219
219
  <tr>
220
- <td align="center"><a href="http://roz.ninja"><img src="https://avatars.githubusercontent.com/u/3948961?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Roz</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Aroziscoding" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=roziscoding" title="Code">πŸ’»</a></td>
220
+ <td align="center"><a href="http://roz.ninja"><img src="https://avatars.githubusercontent.com/u/3948961?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Roz</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Aroziscoding" title="Bug reports">πŸ›</a> <a href="https://github.com/grammyjs/grammY/commits?author=roziscoding" title="Code">πŸ’»</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Aroziscoding" title="Reviewed Pull Requests">πŸ‘€</a></td>
221
+ <td align="center"><a href="https://github.com/daniharo"><img src="https://avatars.githubusercontent.com/u/47931084?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dani Haro</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=daniharo" title="Code">πŸ’»</a> <a href="#plugin-daniharo" title="Plugin/utility libraries">πŸ”Œ</a> <a href="https://github.com/grammyjs/grammY/commits?author=daniharo" title="Documentation">πŸ“–</a></td>
222
+ <td align="center"><a href="https://github.com/Ryukaizen"><img src="https://avatars.githubusercontent.com/u/55140313?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ryukaizen</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=Ryukaizen" title="Documentation">πŸ“–</a></td>
221
223
  </tr>
222
224
  </table>
223
225
 
package/out/bot.d.ts CHANGED
@@ -2,7 +2,7 @@ import { BotError, Composer } from "./composer.js";
2
2
  import { Context } from "./context.js";
3
3
  import { Api } from "./core/api.js";
4
4
  import { type ApiClientOptions, type WebhookReplyEnvelope } from "./core/client.js";
5
- import { type Update, type UserFromGetMe } from "./platform.node.js";
5
+ import { type Update, type UserFromGetMe } from "./types.js";
6
6
  /**
7
7
  * Options that can be specified when running the bot via simple long polling.
8
8
  */
package/out/composer.d.ts CHANGED
@@ -1,9 +1,7 @@
1
- import { type AliasProps, type Context } from "./context.js";
2
- import { type Filter, type FilterQuery } from "./filter.js";
3
- import { type Chat } from "./platform.node.js";
1
+ import { type CallbackQueryContext, type ChatTypeContext, type CommandContext, Context, type GameQueryContext, type HearsContext, type InlineQueryContext, type MaybeArray, type StringWithSuggestions } from "./context.js";
2
+ import { Filter, FilterQuery } from "./filter.js";
3
+ import { type Chat } from "./types.js";
4
4
  declare type MaybePromise<T> = T | Promise<T>;
5
- declare type MaybeArray<T> = T | T[];
6
- declare type StringWithSuggestions<S extends string> = (string & {}) | S;
7
5
  /**
8
6
  * A function of this type is passed as the second parameter to all middleware.
9
7
  * Invoke it to call the downstream middleware and pass on the control flow.
@@ -586,27 +584,58 @@ export declare class Composer<C extends Context> implements MiddlewareObj<C> {
586
584
  */
587
585
  errorBoundary(errorHandler: (error: BotError<C>, next: NextFunction) => MaybePromise<unknown>, ...middleware: Array<Middleware<C>>): Composer<C>;
588
586
  }
589
- export declare type HearsContext<C extends Context> = Filter<Omit<C, "match"> & {
590
- match: Extract<C["match"], string | RegExpMatchArray>;
591
- }, ":text" | ":caption">;
592
- export declare type CommandContext<C extends Context> = Filter<Omit<C, "match"> & {
593
- match: Extract<C["match"], string>;
594
- }, ":entities:bot_command">;
595
- export declare type CallbackQueryContext<C extends Context> = Filter<C, "callback_query:data">;
596
- export declare type GameQueryContext<C extends Context> = Filter<C, "callback_query:game_short_name">;
597
- export declare type InlineQueryContext<C extends Context> = Filter<C, "inline_query">;
598
- export declare type ChatTypeContext<C extends Context, T extends Chat["type"]> = C & Record<"update", ChatTypeUpdate<T>> & ChatType<T> & ChatTypeRecord<"msg", T> & AliasProps<ChatTypeUpdate<T>>;
599
- declare type ChatTypeUpdate<T extends Chat["type"]> = ChatTypeRecord<"message" | "edited_message" | "channel_post" | "edited_channel_post" | "my_chat_member" | "chat_member" | "chat_join_request", T> & Partial<Record<"callback_query", ChatTypeRecord<"message", T>>>;
600
- declare type ChatTypeRecord<K extends string, T extends Chat["type"]> = Partial<Record<K, ChatType<T>>>;
601
- interface ChatType<T extends Chat["type"]> {
602
- chat: {
603
- type: T;
604
- };
605
- }
587
+ /**
588
+ * Type of the middleware that can be passed to `bot.hears`.
589
+ *
590
+ * This helper type can be used to annotate middleware functions that are
591
+ * defined in one place, so that they have the correct type when passed to
592
+ * `bot.hears` in a different place. For instance, this allows for more modular
593
+ * code where handlers are defined in separate files.
594
+ */
606
595
  export declare type HearsMiddleware<C extends Context> = Middleware<HearsContext<C>>;
596
+ /**
597
+ * Type of the middleware that can be passed to `bot.command`.
598
+ *
599
+ * This helper type can be used to annotate middleware functions that are
600
+ * defined in one place, so that they have the correct type when passed to
601
+ * `bot.command` in a different place. For instance, this allows for more
602
+ * modular code where handlers are defined in separate files.
603
+ */
607
604
  export declare type CommandMiddleware<C extends Context> = Middleware<CommandContext<C>>;
605
+ /**
606
+ * Type of the middleware that can be passed to `bot.callbackQuery`.
607
+ *
608
+ * This helper type can be used to annotate middleware functions that are
609
+ * defined in one place, so that they have the correct type when passed to
610
+ * `bot.callbackQuery` in a different plac For instance, this allows for more
611
+ * modular code where handlers are defined in separate files.e.
612
+ */
608
613
  export declare type CallbackQueryMiddleware<C extends Context> = Middleware<CallbackQueryContext<C>>;
614
+ /**
615
+ * Type of the middleware that can be passed to `bot.gameQuery`.
616
+ *
617
+ * This helper type can be used to annotate middleware functions that are
618
+ * defined in one place, so that they have the correct type when passed to
619
+ * `bot.gameQuery` in a different place. For instance, this allows for more
620
+ * modular code where handlers are defined in separate files.
621
+ */
609
622
  export declare type GameQueryMiddleware<C extends Context> = Middleware<GameQueryContext<C>>;
623
+ /**
624
+ * Type of the middleware that can be passed to `bot.inlineQuery`.
625
+ *
626
+ * This helper type can be used to annotate middleware functions that are
627
+ * defined in one place, so that they have the correct type when passed to
628
+ * `bot.inlineQuery` in a different place. For instance, this allows for more
629
+ * modular code where handlers are defined in separate files.
630
+ */
610
631
  export declare type InlineQueryMiddleware<C extends Context> = Middleware<InlineQueryContext<C>>;
632
+ /**
633
+ * Type of the middleware that can be passed to `bot.chatType`.
634
+ *
635
+ * This helper type can be used to annotate middleware functions that are
636
+ * defined in one place, so that they have the correct type when passed to
637
+ * `bot.chatType` in a different place. For instance, this allows for more
638
+ * modular code where handlers are defined in separate files.
639
+ */
611
640
  export declare type ChatTypeMiddleware<C extends Context, T extends Chat["type"]> = Middleware<ChatTypeContext<C, T>>;
612
641
  export {};
package/out/composer.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Composer = exports.run = exports.BotError = void 0;
4
- const filter_js_1 = require("./filter.js");
4
+ const context_js_1 = require("./context.js");
5
5
  // === Middleware errors
6
6
  /**
7
7
  * This error is thrown when middleware throws. It simply wraps the original
@@ -181,7 +181,7 @@ class Composer {
181
181
  * @param middleware The middleware to register behind the given filter
182
182
  */
183
183
  on(filter, ...middleware) {
184
- return this.filter((0, filter_js_1.matchFilter)(filter), ...middleware);
184
+ return this.filter(context_js_1.Context.has.filterQuery(filter), ...middleware);
185
185
  }
186
186
  /**
187
187
  * Registers some middleware that will only be executed when the message
@@ -215,13 +215,7 @@ class Composer {
215
215
  * @param middleware The middleware to register
216
216
  */
217
217
  hears(trigger, ...middleware) {
218
- const trg = triggerFn(trigger);
219
- return this.on([":text", ":caption"]).filter((ctx) => {
220
- var _a, _b;
221
- const msg = (_a = ctx.message) !== null && _a !== void 0 ? _a : ctx.channelPost;
222
- const txt = (_b = msg.text) !== null && _b !== void 0 ? _b : msg.caption;
223
- return match(ctx, txt, trg);
224
- }, ...middleware);
218
+ return this.filter(context_js_1.Context.has.text(trigger), ...middleware);
225
219
  }
226
220
  /**
227
221
  * Registers some middleware that will only be executed when a certain
@@ -279,43 +273,7 @@ class Composer {
279
273
  * @param middleware The middleware to register
280
274
  */
281
275
  command(command, ...middleware) {
282
- const atCommands = new Set();
283
- const noAtCommands = new Set();
284
- toArray(command).forEach((cmd) => {
285
- if (cmd.startsWith("/")) {
286
- throw new Error(`Do not include '/' when registering command handlers (use '${cmd.substring(1)}' not '${cmd}')`);
287
- }
288
- const set = cmd.indexOf("@") === -1 ? noAtCommands : atCommands;
289
- set.add(cmd);
290
- });
291
- return this.on(":entities:bot_command").filter((ctx) => {
292
- var _a;
293
- const msg = (_a = ctx.message) !== null && _a !== void 0 ? _a : ctx.channelPost;
294
- const txt = msg.text;
295
- return msg.entities.some((e) => {
296
- if (e.type !== "bot_command")
297
- return false;
298
- if (e.offset !== 0)
299
- return false;
300
- const cmd = txt.substring(1, e.length);
301
- if (noAtCommands.has(cmd) || atCommands.has(cmd)) {
302
- ctx.match = txt.substring(cmd.length + 1).trimStart();
303
- return true;
304
- }
305
- const index = cmd.indexOf("@");
306
- if (index === -1)
307
- return false;
308
- const atTarget = cmd.substring(index + 1);
309
- if (atTarget !== ctx.me.username)
310
- return false;
311
- const atCommand = cmd.substring(0, index);
312
- if (noAtCommands.has(atCommand)) {
313
- ctx.match = txt.substring(cmd.length + 1).trimStart();
314
- return true;
315
- }
316
- return false;
317
- });
318
- }, ...middleware);
276
+ return this.filter(context_js_1.Context.has.command(command), ...middleware);
319
277
  }
320
278
  /**
321
279
  * Registers some middleware for certain chat types only. For example, you
@@ -349,8 +307,7 @@ class Composer {
349
307
  * @param middleware The middleware to register
350
308
  */
351
309
  chatType(chatType, ...middleware) {
352
- const set = new Set(toArray(chatType));
353
- return this.filter((ctx) => { var _a; return ((_a = ctx.chat) === null || _a === void 0 ? void 0 : _a.type) !== undefined && set.has(ctx.chat.type); }, ...middleware);
310
+ return this.filter(context_js_1.Context.has.chatType(chatType), ...middleware);
354
311
  }
355
312
  /**
356
313
  * Registers some middleware for callback queries, i.e. the updates that
@@ -393,8 +350,7 @@ class Composer {
393
350
  * @param middleware The middleware to register
394
351
  */
395
352
  callbackQuery(trigger, ...middleware) {
396
- const trg = triggerFn(trigger);
397
- return this.on("callback_query:data").filter((ctx) => match(ctx, ctx.callbackQuery.data, trg), ...middleware);
353
+ return this.filter(context_js_1.Context.has.callbackQuery(trigger), ...middleware);
398
354
  }
399
355
  /**
400
356
  * Registers some middleware for game queries, i.e. the updates that
@@ -415,8 +371,7 @@ class Composer {
415
371
  * @param middleware The middleware to register
416
372
  */
417
373
  gameQuery(trigger, ...middleware) {
418
- const trg = triggerFn(trigger);
419
- return this.on("callback_query:game_short_name").filter((ctx) => match(ctx, ctx.callbackQuery.game_short_name, trg), ...middleware);
374
+ return this.filter(context_js_1.Context.has.gameQuery(trigger), ...middleware);
420
375
  }
421
376
  /**
422
377
  * Registers middleware for inline queries. Telegram sends an inline query
@@ -441,8 +396,7 @@ class Composer {
441
396
  * @param middleware The middleware to register
442
397
  */
443
398
  inlineQuery(trigger, ...middleware) {
444
- const trg = triggerFn(trigger);
445
- return this.on("inline_query").filter((ctx) => match(ctx, ctx.inlineQuery.query, trg), ...middleware);
399
+ return this.filter(context_js_1.Context.has.inlineQuery(trigger), ...middleware);
446
400
  }
447
401
  filter(predicate, ...middleware) {
448
402
  const composer = new Composer(...middleware);
@@ -525,7 +479,7 @@ class Composer {
525
479
  lazy(middlewareFactory) {
526
480
  return this.use(async (ctx, next) => {
527
481
  const middleware = await middlewareFactory(ctx);
528
- const arr = toArray(middleware);
482
+ const arr = Array.isArray(middleware) ? middleware : [middleware];
529
483
  await flatten(new Composer(...arr))(ctx, next);
530
484
  });
531
485
  }
@@ -653,22 +607,3 @@ class Composer {
653
607
  }
654
608
  }
655
609
  exports.Composer = Composer;
656
- // === Util functions
657
- function triggerFn(trigger) {
658
- return toArray(trigger).map((t) => typeof t === "string"
659
- ? (txt) => (txt === t ? t : null)
660
- : (txt) => txt.match(t));
661
- }
662
- function match(ctx, content, triggers) {
663
- for (const t of triggers) {
664
- const res = t(content);
665
- if (res) {
666
- ctx.match = res;
667
- return true;
668
- }
669
- }
670
- return false;
671
- }
672
- function toArray(e) {
673
- return Array.isArray(e) ? e : [e];
674
- }
package/out/context.d.ts CHANGED
@@ -1,12 +1,72 @@
1
1
  import { type Api, type Other as OtherApi } from "./core/api.js";
2
2
  import { type Methods, type RawApi } from "./core/client.js";
3
- import { type Chat, type ChatPermissions, type InlineQueryResult, type InputFile, type InputMedia, type InputMediaAudio, type InputMediaDocument, type InputMediaPhoto, type InputMediaVideo, type LabeledPrice, type Message, type PassportElementError, type Update, type User, type UserFromGetMe } from "./platform.node.js";
3
+ import { type Filter, type FilterQuery } from "./filter.js";
4
+ import { type Chat, type ChatPermissions, type InlineQueryResult, type InputFile, type InputMedia, type InputMediaAudio, type InputMediaDocument, type InputMediaPhoto, type InputMediaVideo, type LabeledPrice, type Message, type PassportElementError, type Update, type User, type UserFromGetMe } from "./types.js";
5
+ export declare type MaybeArray<T> = T | T[];
6
+ export declare type StringWithSuggestions<S extends string> = (string & {}) | S;
4
7
  declare type Other<M extends Methods<RawApi>, X extends string = never> = OtherApi<RawApi, M, X>;
5
8
  declare type SnakeToCamelCase<S extends string> = S extends `${infer L}_${infer R}` ? `${L}${Capitalize<SnakeToCamelCase<R>>}` : S;
6
9
  export declare type AliasProps<U> = {
7
10
  [K in string & keyof U as SnakeToCamelCase<K>]: U[K];
8
11
  };
9
12
  declare type RenamedUpdate = AliasProps<Omit<Update, "update_id">>;
13
+ interface StaticHas {
14
+ /**
15
+ * Generates a predicate function that can test context objects for matching
16
+ * the given filter query. This uses the same logic as `bot.on`.
17
+ *
18
+ * @param filter The filter query to check
19
+ */
20
+ filterQuery<Q extends FilterQuery>(filter: Q | Q[]): <C extends Context>(ctx: C) => ctx is Filter<C, Q>;
21
+ /**
22
+ * Generates a predicate function that can test context objects for
23
+ * containing the given text, or for the text to match the given regular
24
+ * expression. This uses the same logic as `bot.hears`.
25
+ *
26
+ * @param trigger The string or regex to match
27
+ */
28
+ text(trigger: MaybeArray<string | RegExp>): <C extends Context>(ctx: C) => ctx is HearsContext<C>;
29
+ /**
30
+ * Generates a predicate function that can test context objects for
31
+ * containing a command. This uses the same logic as `bot.command`.
32
+ *
33
+ * @param command The command to match
34
+ */
35
+ command<S extends string>(command: MaybeArray<StringWithSuggestions<S | "start" | "help" | "settings">>): <C extends Context>(ctx: C) => ctx is CommandContext<C>;
36
+ /**
37
+ * Generates a predicate function that can test context objects for
38
+ * belonging to a chat with the given chat type. This uses the same logic as
39
+ * `bot.chatType`.
40
+ *
41
+ * @param chatType The chat type to match
42
+ */
43
+ chatType<T extends Chat["type"]>(chatType: MaybeArray<T>): <C extends Context>(ctx: C) => ctx is ChatTypeContext<C, T>;
44
+ /**
45
+ * Generates a predicate function that can test context objects for
46
+ * containing the given callback query, or for the callback query data to
47
+ * match the given regular expression. This uses the same logic as
48
+ * `bot.callbackQuery`.
49
+ *
50
+ * @param trigger The string or regex to match
51
+ */
52
+ callbackQuery(trigger: MaybeArray<string | RegExp>): <C extends Context>(ctx: C) => ctx is CallbackQueryContext<C>;
53
+ /**
54
+ * Generates a predicate function that can test context objects for
55
+ * containing the given game query, or for the game name to match the given
56
+ * regular expression. This uses the same logic as `bot.gameQuery`.
57
+ *
58
+ * @param trigger The string or regex to match
59
+ */
60
+ gameQuery(trigger: MaybeArray<string | RegExp>): <C extends Context>(ctx: C) => ctx is GameQueryContext<C>;
61
+ /**
62
+ * Generates a predicate function that can test context objects for
63
+ * containing the given inline query, or for the inline query to match the
64
+ * given regular expression. This uses the same logic as `bot.inlineQuery`.
65
+ *
66
+ * @param trigger The string or regex to match
67
+ */
68
+ inlineQuery(trigger: MaybeArray<string | RegExp>): <C extends Context>(ctx: C) => ctx is InlineQueryContext<C>;
69
+ }
10
70
  /**
11
71
  * When your bot receives a message, Telegram sends an update object to your
12
72
  * bot. The update contains information about the chat, the user, and of course
@@ -133,6 +193,82 @@ export declare class Context implements RenamedUpdate {
133
193
  * `(ctx.callbackQuery ?? ctx.chosenInlineResult)?.inline_message_id`
134
194
  */
135
195
  get inlineMessageId(): string | undefined;
196
+ /**
197
+ * `Context.has` is an object that contains a number of useful functions for
198
+ * probing context objects. Each of these functions can generate a predicate
199
+ * function, to which you can pass context objects in order to check if a
200
+ * condition holds for the respective context object.
201
+ *
202
+ * For example, you can call `Context.has.filterQuery(":text")` to generate
203
+ * a predicate function that tests context objects for containing text:
204
+ * ```ts
205
+ * const hasText = Context.has.filterQuery(":text");
206
+ *
207
+ * if (hasText(ctx0)) {} // `ctx0` matches the filter query `:text`
208
+ * if (hasText(ctx1)) {} // `ctx1` matches the filter query `:text`
209
+ * if (hasText(ctx2)) {} // `ctx2` matches the filter query `:text`
210
+ * ```
211
+ * These predicate funtions are used internally by the has-methods that are
212
+ * installed on every context object. This means that calling
213
+ * `ctx.has(":text")` is equivalent to
214
+ * `Context.has.filterQuery(":text")(ctx)`.
215
+ */
216
+ static has: StaticHas;
217
+ /**
218
+ * Returns `true` if this context object matches the given filter query, and
219
+ * `false` otherwise. This uses the same logic as `bot.on`.
220
+ *
221
+ * @param filter The filter query to check
222
+ */
223
+ has<Q extends FilterQuery>(filter: Q | Q[]): this is Filter<this, Q>;
224
+ /**
225
+ * Returns `true` if this context object contains the given text, or if it
226
+ * contains text that matches the given regular expression. It returns
227
+ * `false` otherwise. This uses the same logic as `bot.hears`.
228
+ *
229
+ * @param trigger The string or regex to match
230
+ */
231
+ hasText(trigger: MaybeArray<string | RegExp>): this is HearsContext<this>;
232
+ /**
233
+ * Returns `true` if this context object contains the given command, and
234
+ * `false` otherwise. This uses the same logic as `bot.command`.
235
+ *
236
+ * @param command The command to match
237
+ */
238
+ hasCommand<S extends string>(command: MaybeArray<StringWithSuggestions<S | "start" | "help" | "settings">>): this is CommandContext<this>;
239
+ /**
240
+ * Returns `true` if this context object belongs to a chat with the given
241
+ * chat type, and `false` otherwise. This uses the same logic as
242
+ * `bot.chatType`.
243
+ *
244
+ * @param chatType The chat type to match
245
+ */
246
+ hasChatType<T extends Chat["type"]>(chatType: MaybeArray<T>): this is ChatTypeContext<this, T>;
247
+ /**
248
+ * Returns `true` if this context object contains the given callback query,
249
+ * or if the contained callback query data matches the given regular
250
+ * expression. It returns `false` otherwise. This uses the same logic as
251
+ * `bot.callbackQuery`.
252
+ *
253
+ * @param trigger The string or regex to match
254
+ */
255
+ hasCallbackQuery(trigger: MaybeArray<string | RegExp>): this is CallbackQueryContext<this>;
256
+ /**
257
+ * Returns `true` if this context object contains the given game query, or
258
+ * if the contained game query matches the given regular expression. It
259
+ * returns `false` otherwise. This uses the same logic as `bot.gameQuery`.
260
+ *
261
+ * @param trigger The string or regex to match
262
+ */
263
+ hasGameQuery(trigger: MaybeArray<string | RegExp>): this is GameQueryContext<this>;
264
+ /**
265
+ * Returns `true` if this context object contains the given inline query, or
266
+ * if the contained inline query matches the given regular expression. It
267
+ * returns `false` otherwise. This uses the same logic as `bot.inlineQuery`.
268
+ *
269
+ * @param trigger The string or regex to match
270
+ */
271
+ hasInlineQuery(trigger: MaybeArray<string | RegExp>): this is InlineQueryContext<this>;
136
272
  /**
137
273
  * Context-aware alias for `api.sendMessage`. Use this method to send text messages. On success, the sent Message is returned.
138
274
  *
@@ -848,5 +984,84 @@ export declare class Context implements RenamedUpdate {
848
984
  */
849
985
  replyWithGame(game_short_name: string, other?: Other<"sendGame", "chat_id" | "game_short_name">, signal?: AbortSignal): Promise<Message.GameMessage>;
850
986
  }
987
+ /**
988
+ * Type of the context object that is available inside the handlers for
989
+ * `bot.hears`.
990
+ *
991
+ * This helper type can be used to narrow down context objects the same way how
992
+ * `bot.hears` does it. This allows you to annotate context objects in
993
+ * middleware that is not directly passed to `bot.hears`, hence not inferring
994
+ * the correct type automatically. That way, handlers can be defined in separate
995
+ * files and still have the correct types.
996
+ */
997
+ export declare type HearsContext<C extends Context> = Filter<NarrowMatch<C, string | RegExpMatchArray>, ":text" | ":caption">;
998
+ /**
999
+ * Type of the context object that is available inside the handlers for
1000
+ * `bot.command`.
1001
+ *
1002
+ * This helper type can be used to narrow down context objects the same way how
1003
+ * `bot.command` does it. This allows you to annotate context objects in
1004
+ * middleware that is not directly passed to `bot.command`, hence not inferring
1005
+ * the correct type automatically. That way, handlers can be defined in separate
1006
+ * files and still have the correct types.
1007
+ */
1008
+ export declare type CommandContext<C extends Context> = Filter<NarrowMatch<C, string>, ":entities:bot_command">;
1009
+ declare type NarrowMatch<C extends Context, T extends C["match"]> = {
1010
+ [K in keyof C]: K extends "match" ? (T extends C[K] ? T : never) : C[K];
1011
+ };
1012
+ /**
1013
+ * Type of the context object that is available inside the handlers for
1014
+ * `bot.callbackQuery`.
1015
+ *
1016
+ * This helper type can be used to annotate narrow down context objects the same
1017
+ * way `bot.callbackQuery` does it. This allows you to how context objects in
1018
+ * middleware that is not directly passed to `bot.callbackQuery`, hence not
1019
+ * inferring the correct type automatically. That way, handlers can be defined
1020
+ * in separate files and still have the correct types.
1021
+ */
1022
+ export declare type CallbackQueryContext<C extends Context> = Filter<C, "callback_query:data">;
1023
+ /**
1024
+ * Type of the context object that is available inside the handlers for
1025
+ * `bot.gameQuery`.
1026
+ *
1027
+ * This helper type can be used to narrow down context objects the same way how
1028
+ * `bot.gameQuery` does it. This allows you to annotate context objects in
1029
+ * middleware that is not directly passed to `bot.gameQuery`, hence not
1030
+ * inferring the correct type automatically. That way, handlers can be defined
1031
+ * in separate files and still have the correct types.
1032
+ */
1033
+ export declare type GameQueryContext<C extends Context> = Filter<C, "callback_query:game_short_name">;
1034
+ /**
1035
+ * Type of the context object that is available inside the handlers for
1036
+ * `bot.inlineQuery`.
1037
+ *
1038
+ * This helper type can be used to narrow down context objects the same way how
1039
+ * annotate `bot.inlineQuery` does it. This allows you to context objects in
1040
+ * middleware that is not directly passed to `bot.inlineQuery`, hence not
1041
+ * inferring the correct type automatically. That way, handlers can be defined
1042
+ * in separate files and still have the correct types.
1043
+ */
1044
+ export declare type InlineQueryContext<C extends Context> = Filter<C, "inline_query">;
1045
+ /**
1046
+ * Type of the context object that is available inside the handlers for
1047
+ * `bot.chatType`.
1048
+ *
1049
+ * This helper type can be used to narrow down context objects the same way how
1050
+ * `bot.chatType` does it. This allows you to annotate context objects in
1051
+ * middleware that is not directly passed to `bot.chatType`, hence not inferring
1052
+ * the correct type automatically. That way, handlers can be defined in separate
1053
+ * files and still have the correct types.
1054
+ */
1055
+ export declare type ChatTypeContext<C extends Context, T extends Chat["type"]> = C & Record<"update", ChatTypeUpdate<T>> & ChatType<T> & ChatTypeRecord<"msg", T> & AliasProps<ChatTypeUpdate<T>>;
1056
+ declare type ChatTypeUpdate<T extends Chat["type"]> = ChatTypeRecord<"message" | "edited_message" | "channel_post" | "edited_channel_post" | "my_chat_member" | "chat_member" | "chat_join_request", T> & Partial<Record<"callback_query", ChatTypeRecord<"message", T>>> & ConstrainUpdatesByChatType<T>;
1057
+ declare type ConstrainUpdatesByChatType<T extends Chat["type"]> = Record<[
1058
+ T
1059
+ ] extends ["channel"] ? "message" | "edited_message" : "channel_post" | "edited_channel_post", undefined>;
1060
+ declare type ChatTypeRecord<K extends string, T extends Chat["type"]> = Partial<Record<K, ChatType<T>>>;
1061
+ interface ChatType<T extends Chat["type"]> {
1062
+ chat: {
1063
+ type: T;
1064
+ };
1065
+ }
851
1066
  import { AbortSignal } from "./shim.node.js";
852
1067
  export {};