From 68f8cc236f8f7e873457e8d6e83f73daeef4fbaa Mon Sep 17 00:00:00 2001 From: Hero Protagonist Date: Thu, 23 Jan 2025 07:23:45 -0300 Subject: [PATCH] feat: add `ctx.txt` (#732) --- src/context.ts | 9 +++++++++ src/filter.ts | 3 +++ test/context.test.ts | 15 +++++++++++++++ test/deps.test.ts | 6 +++++- test/filter.test.ts | 23 +++++++++++++++++++++++ 5 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/context.ts b/src/context.ts index 36c1a39c..d78ae264 100644 --- a/src/context.ts +++ b/src/context.ts @@ -520,6 +520,15 @@ export class Context implements RenamedUpdate { this.callbackQuery?.message ); } + /** + * Get the message text from wherever possible. Alias for `this.msg?.text ?? + * this.msg?.caption`. + */ + get txt(): string | undefined { + // Keep in sync with types in `filter.ts`. + const msg = this.msg; + return msg?.text ?? msg?.caption; + } /** * Get the chat object from wherever possible. Alias for `(this.msg ?? * this.deletedBusinessMessages ?? this.messageReaction ?? diff --git a/src/filter.ts b/src/filter.ts index 23b6cf37..bf2fa32b 100644 --- a/src/filter.ts +++ b/src/filter.ts @@ -601,6 +601,9 @@ interface Shortcuts { : [U["callback_query"]] extends [object] ? U["callback_query"]["message"] : undefined; + txt: [Shortcuts["msg"]] extends [{ text: string } | { caption: string }] + ? string + : undefined; chat: [U["callback_query"]] extends [object] ? NonNullable["chat"] | undefined : [Shortcuts["msg"]] extends [object] ? Shortcuts["msg"]["chat"] diff --git a/test/context.test.ts b/test/context.test.ts index 69e9e508..fd6124af 100644 --- a/test/context.test.ts +++ b/test/context.test.ts @@ -147,6 +147,21 @@ describe("Context", () => { ctx = new Context(up, api, me); assertEquals(ctx.msg, up.edited_business_message); }); + it(".txt should aggregate text", () => { + let up: Update, ctx: Context; + const mc = { + caption: "b", + from: u, + chat: c, + sender_chat: c, + } as Message; + up = { message: update.message } as Update; + ctx = new Context(up, api, me); + assertEquals(ctx.txt, up.message?.text); + up = { message: mc } as Update; + ctx = new Context(up, api, me); + assertEquals(ctx.txt, up.message?.caption); + }); it(".chat should aggregate chats", () => { let up: Update, ctx: Context; diff --git a/test/deps.test.ts b/test/deps.test.ts index 216b3590..11ad94a6 100644 --- a/test/deps.test.ts +++ b/test/deps.test.ts @@ -12,7 +12,11 @@ export { } from "jsr:@std/assert"; export { afterEach, beforeEach, describe, it } from "jsr:@std/testing/bdd"; export { type Spy, spy, type Stub, stub } from "jsr:@std/testing/mock"; -export { assertType, type IsExact } from "jsr:@std/testing/types"; +export { + assertType, + type IsExact, + type IsNullable, +} from "jsr:@std/testing/types"; export { type IsMutuallyAssignable } from "jsr:@std/testing/unstable-types"; /** diff --git a/test/filter.test.ts b/test/filter.test.ts index 20b9d894..2ea2a172 100644 --- a/test/filter.test.ts +++ b/test/filter.test.ts @@ -3,7 +3,9 @@ import { assert, assertEquals, assertThrows, + assertType, describe, + type IsNullable, it, } from "./deps.test.ts"; @@ -143,4 +145,25 @@ describe("matchFilter", () => { throw "never"; } }); + + it("should narrow down context shortcut types", () => { + const ctx = new Context( + // deno-lint-ignore no-explicit-any + {} as any, + // deno-lint-ignore no-explicit-any + undefined as any, + // deno-lint-ignore no-explicit-any + undefined as any, + ); + if (matchFilter([":text", ":caption"])(ctx)) { + assertType>(false); + assertType>(false); + assertType>(false); + assertType>(false); + assertType>(false); + } + if (matchFilter("message")(ctx)) { + assertType>(false); + } + }); });