import type { CallbackQuery, CommonMessageBundle, Message, Update, } from '@telegraf/types' import { DistinctKeys, KeyedDistinct, Guarded } from './core/helpers/util' export type Filter = (update: Update) => update is U export { Guarded } export type AllGuarded[]> = Fs extends [ infer A, ...infer B, ] ? B extends [] ? Guarded : // TS doesn't know otherwise that B is Filter[] B extends Filter[] ? Guarded & AllGuarded : never : never export const message = []>(...keys: Ks) => ( update: Update ): update is Update.MessageUpdate> => { if (!('message' in update)) return false for (const key of keys) { if (!(key in update.message)) return false } return true } export const editedMessage = []>(...keys: Ks) => ( update: Update ): update is Update.EditedMessageUpdate< KeyedDistinct > => { if (!('edited_message' in update)) return false for (const key of keys) { if (!(key in update.edited_message)) return false } return true } export const channelPost = []>(...keys: Ks) => ( update: Update ): update is Update.ChannelPostUpdate> => { if (!('channel_post' in update)) return false for (const key of keys) { if (!(key in update.channel_post)) return false } return true } export const editedChannelPost = []>(...keys: Ks) => ( update: Update ): update is Update.EditedChannelPostUpdate< KeyedDistinct > => { if (!('edited_channel_post' in update)) return false for (const key of keys) { if (!(key in update.edited_channel_post)) return false } return true } export const callbackQuery = []>(...keys: Ks) => ( update: Update ): update is Update.CallbackQueryUpdate< KeyedDistinct > => { if (!('callback_query' in update)) return false for (const key of keys) { if (!(key in update.callback_query)) return false } return true } /** Any of the provided filters must match */ export const anyOf = ( ...filters: { [UIdx in keyof Us]: Filter } ) => (update: Update): update is Us[number] => { for (const filter of filters) if (filter(update)) return true return false } /** All of the provided filters must match */ export const allOf = []>(...filters: Fs) => (update: Update): update is AllGuarded => { for (const filter of filters) if (!filter(update)) return false return true }