import type { BotApiMethods } from "@yaebal/types"; import type { ResponseParameters } from "./telegram-types.js"; import type { WebhookReplyEnvelope } from "./webhook.js"; /** * resolve a local `media.path()` into bytes. runtime-specific (node:fs, Bun.file, * Deno.readFile), so it's injected rather than imported — that keeps `@yaebal/core` * free of any `node:` import and loadable on edge/web. the `yaebal` package wires an * auto-detecting default; absent ⇒ `media.path()` throws (e.g. on Cloudflare Workers). */ export type FileReader = (path: string) => Promise; /** * thrown when the HTTP layer fails before a Bot API answer exists — the server * (or a proxy in front of it) replied with something that isn't the JSON envelope * (e.g. an HTML 502 page). carries the method and HTTP status for context; * `TelegramError` stays reserved for real `ok: false` API answers. */ export declare class HttpError extends Error { readonly method: string; readonly status: number; readonly statusText: string; constructor(method: string, status: number, statusText: string); } /** thrown when telegram replies with `ok: false`. */ export declare class TelegramError extends Error { readonly method: string; readonly code: number; readonly description: string; readonly parameters?: ResponseParameters; constructor(method: string, code: number, description: string, parameters?: ResponseParameters); } /** inspect/rewrite params before a request. return new params to replace them. */ export type BeforeHook = (method: string, params: Record | undefined) => Record | undefined | Promise | undefined>; /** inspect/rewrite the result after a successful request. return a value to replace it. */ export type AfterHook = (method: string, params: Record | undefined, result: unknown) => unknown | Promise; /** what an error hook can ask the client to do. */ export interface ErrorAction { /** re-run the same call. */ retry?: boolean; /** wait this many ms before retrying. */ delayMs?: number; } /** runs when a request throws. `attempt` is the (1-based) attempt that just failed. */ export type ErrorHook = (method: string, error: unknown, attempt: number, params: Record | undefined) => ErrorAction | undefined | Promise; /** per-call options — currently just cancellation. */ export interface CallOptions { /** abort the underlying fetch (e.g. `Bot.stop()` cancels the long poll with this). */ signal?: AbortSignal; } /** * the API client. every Bot API method is fully typed via the code-generated * {@link BotApiMethods} (the proxy materialises them at runtime); `call` stays as * the untyped passthrough (the puregram idea — a brand-new Bot API method, or * params built dynamically as plain records, work before/without types). * `before` / `after` / `onError` are the extension points plugins hang off of. */ export interface Api extends BotApiMethods { call(method: string, params?: Record, options?: CallOptions): Promise; /** build the download URL for a `file_path` from `getFile`. contains the bot token — don't log it. */ fileUrl(filePath: string): string; /** * `getFile(fileId)` + a fetch of the result — the file's bytes in one call, no * runtime-specific filesystem needed. throws if telegram reports no `file_path` * (the file exceeded the 20MB Bot API download cap) or the download itself fails. */ downloadFile(fileId: string, options?: CallOptions): Promise<{ filePath: string; bytes: Uint8Array; }>; /** register a hook that runs before every request; may rewrite params. */ before(hook: BeforeHook): Api; /** register a hook that runs after every successful request; may rewrite the result. */ after(hook: AfterHook): Api; /** register a hook that runs when a request throws; may request a retry. */ onError(hook: ErrorHook): Api; } export interface ApiOptions { /** * bare API origin, no trailing slash and no `/bot` — the client appends * `/bot/` itself. e.g. `"https://api.telegram.org"` or a local * bot-api server `"http://localhost:8081"`. a value that already ends in * `/bot` (a common GramIO-migration habit) is detected and the suffix is * stripped with a `console.warn`, rather than silently doubling up and 401ing. * defaults to the public origin. */ apiRoot?: string; /** resolve `media.path()` to bytes. injected per runtime; absent ⇒ path media throws (e.g. edge). */ readFile?: FileReader; } interface EncodedRequest { body: string | FormData | undefined; contentType?: string; } /** * encode request params. plain params (and `url`/`fileId` media) go as JSON; if any * uploadable media is present — at the top level or nested (`sendMediaGroup` & co) — * the whole request becomes multipart, with each upload attached via `attach://`. * exported for testing. */ export declare function encodeRequest(params: Record | undefined, readFile?: FileReader): Promise; /** builds a callable API client with before/after/error hooks. */ export declare function createApi(token: string, options?: ApiOptions): Api; /** * a per-update view of an api that offers each call to a webhook-reply envelope * first: the one call the envelope claims becomes the webhook's HTTP response * (its promise resolves `true` — telegram doesn't send back a result); everything * else falls through to the real client, hooks and retries included. calls that * carry uploads are never offered — a webhook reply must be plain JSON. */ export declare function withReplyEnvelope(api: Api, envelope: WebhookReplyEnvelope): Api; export {}; //# sourceMappingURL=api.d.ts.map