-
Notifications
You must be signed in to change notification settings - Fork 99
/
types.web.ts
118 lines (110 loc) · 4.32 KB
/
types.web.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// === Needed imports
import { basename } from "https://deno.land/std@0.170.0/path/mod.ts";
import { type InputFileProxy } from "https://esm.sh/@grammyjs/types@2.10.2";
import { toRaw } from "./platform.deno.ts";
// === Export all API types
export * from "https://esm.sh/@grammyjs/types@2.10.2";
/** Something that looks like a URL. */
interface URLLike {
/**
* Identifier of the resource. Must be in a format that can be parsed by the
* URL constructor.
*/
url: string;
}
// === InputFile handling and File augmenting
/**
* An `InputFile` wraps a number of different sources for [sending
* files](https://grammy.dev/guide/files.html#uploading-your-own-file).
*
* It corresponds to the `InputFile` type in the [Telegram Bot API
* Reference](https://core.telegram.org/bots/api#inputfile).
*/
export class InputFile {
private consumed = false;
private readonly fileData: ConstructorParameters<typeof InputFile>[0];
/**
* Optional name of the constructed `InputFile` instance.
*
* Check out the
* [documentation](https://grammy.dev/guide/files.html#uploading-your-own-file)
* on sending files with `InputFile`.
*/
public readonly filename?: string;
/**
* Constructs an `InputFile` that can be used in the API to send files.
*
* @param file A URL to a file or a `Blob` or any form of `Uint8Array` that specifies the file data
* @param filename Optional name of the file
*/
constructor(
file:
| Blob
| URL
| URLLike
| Uint8Array
| ReadableStream<Uint8Array>
| Iterable<Uint8Array>
| AsyncIterable<Uint8Array>,
filename?: string,
) {
this.fileData = file;
filename ??= this.guessFilename(file);
this.filename = filename;
}
private guessFilename(
file: ConstructorParameters<typeof InputFile>[0],
): string | undefined {
if (typeof file === "string") return basename(file);
if (typeof file !== "object") return undefined;
if ("url" in file) return basename(file.url);
if (!(file instanceof URL)) return undefined;
return basename(file.pathname) || basename(file.hostname);
}
[toRaw](): Uint8Array | Iterable<Uint8Array> | AsyncIterable<Uint8Array> {
if (this.consumed) {
throw new Error("Cannot reuse InputFile data source!");
}
const data = this.fileData;
// Handle local files
if (data instanceof Blob) return data.stream();
// Handle URL and URLLike objects
if (data instanceof URL) return fetchFile(data);
if ("url" in data) return fetchFile(data.url);
// Mark streams and iterators as consumed
if (!(data instanceof Uint8Array)) this.consumed = true;
// Return buffers and byte streams as-is
return data;
}
}
async function* fetchFile(url: string | URL): AsyncIterable<Uint8Array> {
const { body } = await fetch(url);
if (body === null) {
throw new Error(`Download failed, no response body from '${url}'`);
}
yield* body;
}
// === Export InputFile types
type GrammyTypes = InputFileProxy<InputFile>;
/** Wrapper type to bundle all methods of the Telegram API */
export type ApiMethods = GrammyTypes["Telegram"];
/** Utility type providing the argument type for the given method name or `{}` if the method does not take any parameters */
export type Opts<M extends keyof GrammyTypes["Telegram"]> =
GrammyTypes["Opts"][M];
/** This object represents the content of a media message to be sent. It should be one of
- InputMediaAnimation
- InputMediaDocument
- InputMediaAudio
- InputMediaPhoto
- InputMediaVideo */
export type InputMedia = GrammyTypes["InputMedia"];
/** Represents a photo to be sent. */
export type InputMediaPhoto = GrammyTypes["InputMediaPhoto"];
/** Represents a video to be sent. */
export type InputMediaVideo = GrammyTypes["InputMediaVideo"];
/** Represents an animation file (GIF or H.264/MPEG-4 AVC video without sound) to be sent. */
export type InputMediaAnimation = GrammyTypes["InputMediaAnimation"];
/** Represents an audio file to be treated as music to be sent. */
export type InputMediaAudio = GrammyTypes["InputMediaAudio"];
/** Represents a general file to be sent. */
export type InputMediaDocument = GrammyTypes["InputMediaDocument"];