@mtcute/bun 0.17.0 → 0.18.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/client.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { Readable } from 'node:stream';
2
1
  import { FileDownloadLocation, FileDownloadParameters, ITelegramStorageProvider, PartialOnly, User } from '@mtcute/core';
3
2
  import { BaseTelegramClientOptions as BaseTelegramClientOptionsBase, TelegramClientOptions, BaseTelegramClient as BaseTelegramClientBase, TelegramClient as TelegramClientBase } from '@mtcute/core/client.js';
3
+ import { Readable } from 'node:stream';
4
4
  export type { TelegramClientOptions };
5
- export interface BaseTelegramClientOptions extends PartialOnly<Omit<BaseTelegramClientOptionsBase, 'storage'>, 'transport' | 'crypto'> {
5
+ export interface BaseTelegramClientOptions extends PartialOnly<Omit<BaseTelegramClientOptionsBase, 'storage'>, 'transport' | 'crypto' | 'platform'> {
6
6
  /**
7
7
  * Storage to use for this client.
8
8
  *
@@ -12,13 +12,6 @@ export interface BaseTelegramClientOptions extends PartialOnly<Omit<BaseTelegram
12
12
  * @default `"client.session"`
13
13
  */
14
14
  storage?: string | ITelegramStorageProvider;
15
- /**
16
- * **ADVANCED USE ONLY**
17
- *
18
- * Whether to not set up the platform.
19
- * This is useful if you call `setPlatform` yourself.
20
- */
21
- platformless?: boolean;
22
15
  }
23
16
  export declare class BaseTelegramClient extends BaseTelegramClientBase {
24
17
  constructor(opts: BaseTelegramClientOptions);
package/client.js ADDED
@@ -0,0 +1,90 @@
1
+ import { createInterface } from "node:readline";
2
+ import { unknownToError } from "@fuman/utils";
3
+ import { BaseTelegramClient as BaseTelegramClient$1, TelegramClient as TelegramClient$1 } from "@mtcute/core/client.js";
4
+ import { downloadToFile } from "./methods/download-file.js";
5
+ import { downloadAsNodeStream } from "./methods/download-node-stream.js";
6
+ import { BunPlatform } from "./platform.js";
7
+ import { SqliteStorage } from "./sqlite/index.js";
8
+ import { BunCryptoProvider } from "./utils/crypto.js";
9
+ import { TcpTransport } from "./utils/tcp.js";
10
+ class BaseTelegramClient extends BaseTelegramClient$1 {
11
+ constructor(opts) {
12
+ super({
13
+ crypto: new BunCryptoProvider(),
14
+ transport: new TcpTransport(),
15
+ platform: new BunPlatform(),
16
+ ...opts,
17
+ storage: typeof opts.storage === "string" ? new SqliteStorage(opts.storage) : opts.storage ?? new SqliteStorage("client.session")
18
+ });
19
+ }
20
+ }
21
+ class TelegramClient extends TelegramClient$1 {
22
+ constructor(opts) {
23
+ if ("client" in opts) {
24
+ super(opts);
25
+ return;
26
+ }
27
+ super({
28
+ client: new BaseTelegramClient(opts),
29
+ disableUpdates: opts.disableUpdates,
30
+ skipConversationUpdates: opts.skipConversationUpdates,
31
+ updates: opts.updates
32
+ });
33
+ }
34
+ _rl;
35
+ /**
36
+ * Tiny wrapper over Node `readline` package
37
+ * for simpler user input for `.start()` method.
38
+ *
39
+ * Associated `readline` interface is closed
40
+ * after `start()` returns, or with the client.
41
+ *
42
+ * @param text Text of the question
43
+ */
44
+ input(text) {
45
+ if (!this._rl) {
46
+ this._rl = createInterface({
47
+ input: process.stdin,
48
+ output: process.stdout
49
+ });
50
+ }
51
+ return new Promise((res) => this._rl?.question(text, res));
52
+ }
53
+ close() {
54
+ this._rl?.close();
55
+ return super.close();
56
+ }
57
+ start(params = {}) {
58
+ if (!params.botToken) {
59
+ if (!params.phone) params.phone = () => this.input("phone > ");
60
+ if (!params.code) params.code = () => this.input("code > ");
61
+ if (!params.password) {
62
+ params.password = () => this.input("2fa password > ");
63
+ }
64
+ }
65
+ return super.start(params).then((user) => {
66
+ if (this._rl) {
67
+ this._rl.close();
68
+ delete this._rl;
69
+ }
70
+ return user;
71
+ });
72
+ }
73
+ run(params, then) {
74
+ if (typeof params === "function") {
75
+ then = params;
76
+ params = {};
77
+ }
78
+ this.start(params).then(then).catch((err) => this.onError.emit(unknownToError(err)));
79
+ }
80
+ downloadToFile(filename, location, params) {
81
+ return downloadToFile(this, filename, location, params);
82
+ }
83
+ downloadAsNodeStream(location, params) {
84
+ return downloadAsNodeStream(this, location, params);
85
+ }
86
+ }
87
+ export {
88
+ BaseTelegramClient,
89
+ TelegramClient
90
+ };
package/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './client.js';
2
2
  export * from './platform.js';
3
3
  export * from './sqlite/index.js';
4
4
  export * from './utils/crypto.js';
5
+ export * from './utils/proxies.js';
5
6
  export * from './utils/tcp.js';
6
7
  export * from './worker.js';
7
8
  export * from '@mtcute/core';
package/index.js CHANGED
@@ -1,537 +1,24 @@
1
- import { createInterface } from "node:readline";
2
- import { BaseTelegramClient as BaseTelegramClient$1, TelegramClient as TelegramClient$1 } from "@mtcute/core/client.js";
3
- import { setPlatform } from "@mtcute/core/platform.js";
4
- import { downloadToFile, downloadAsNodeStream } from "./chunks/es/BmtxbrWZ.js";
5
- import * as os from "node:os";
6
- import { createReadStream, ReadStream } from "node:fs";
7
- import { stat, readFile } from "node:fs/promises";
8
- import { basename } from "node:path";
9
- import { Readable } from "node:stream";
10
- import { BaseSqliteStorageDriver, BaseSqliteStorage, TransportState, MtcuteError, IntermediatePacketCodec } from "@mtcute/core";
1
+ import { BaseTelegramClient, TelegramClient } from "./client.js";
2
+ import { BunPlatform } from "./platform.js";
3
+ import { SqliteStorage } from "./sqlite/index.js";
4
+ import { BunCryptoProvider } from "./utils/crypto.js";
5
+ import { HttpProxyTcpTransport, MtProxyTcpTransport, SocksProxyTcpTransport } from "./utils/proxies.js";
6
+ import { TcpTransport } from "./utils/tcp.js";
7
+ import { TelegramWorker, TelegramWorkerPort } from "./worker.js";
11
8
  export * from "@mtcute/core";
12
- import { Database } from "bun:sqlite";
13
- import { deflateSync, gunzipSync } from "node:zlib";
14
- import { pbkdf2 } from "node:crypto";
15
- import { BaseCryptoProvider } from "@mtcute/core/utils.js";
16
- import { initSync, ige256Encrypt, ige256Decrypt, createCtr256, ctr256, freeCtr256 } from "@mtcute/wasm";
17
- import EventEmitter from "events";
18
- import { parentPort, Worker } from "node:worker_threads";
19
- import { TelegramWorker as TelegramWorker$1, TelegramWorkerPort as TelegramWorkerPort$1 } from "@mtcute/core/worker.js";
20
9
  export * from "@mtcute/html-parser";
21
10
  export * from "@mtcute/markdown-parser";
22
- function nodeStreamToWeb(stream) {
23
- if (typeof Readable.toWeb === "function") {
24
- return Readable.toWeb(stream);
25
- }
26
- stream.pause();
27
- return new ReadableStream({
28
- start(c) {
29
- stream.on("data", (chunk) => {
30
- c.enqueue(chunk);
31
- });
32
- stream.on("end", () => {
33
- c.close();
34
- });
35
- stream.on("error", (err) => {
36
- c.error(err);
37
- });
38
- },
39
- pull() {
40
- stream.resume();
41
- }
42
- });
43
- }
44
- async function normalizeFile$1(file) {
45
- if (typeof file === "string") {
46
- file = createReadStream(file);
47
- }
48
- if (file instanceof ReadStream) {
49
- const fileName = basename(file.path.toString());
50
- const fileSize = await stat(file.path.toString()).then((stat2) => stat2.size);
51
- return {
52
- file: nodeStreamToWeb(file),
53
- fileName,
54
- fileSize
55
- };
56
- }
57
- if (file instanceof Readable) {
58
- return {
59
- file: nodeStreamToWeb(file)
60
- };
61
- }
62
- return null;
63
- }
64
- let installed = false;
65
- let handled = false;
66
- const callbacks = /* @__PURE__ */ new Set();
67
- const myHandlers = /* @__PURE__ */ new Map();
68
- function register(shouldManuallyExit, signal, event) {
69
- function eventHandler() {
70
- if (handled) {
71
- return;
72
- }
73
- handled = true;
74
- for (const callback of callbacks) {
75
- callback();
76
- }
77
- for (const [event2, handler] of myHandlers) {
78
- process.off(event2, handler);
79
- }
80
- if (shouldManuallyExit) {
81
- process.kill(process.pid, signal);
82
- }
83
- }
84
- process.on(event, eventHandler);
85
- myHandlers.set(event, eventHandler);
86
- }
87
- function beforeExit(fn) {
88
- if (typeof process === "undefined") return () => {
89
- };
90
- if (!installed) {
91
- installed = true;
92
- register(true, 0, "beforeExit");
93
- register(true, 2, "SIGINT");
94
- register(true, 15, "SIGTERM");
95
- register(false, 15, "exit");
96
- }
97
- callbacks.add(fn);
98
- return () => {
99
- callbacks.delete(fn);
100
- };
101
- }
102
- const isTty = typeof process === "object" && Boolean(process.stdout?.isTTY);
103
- const BASE_FORMAT = isTty ? "%s [%s] [%s%s\x1B[0m] " : "%s [%s] [%s] ";
104
- const LEVEL_NAMES = isTty ? [
105
- "",
106
- // OFF
107
- "\x1B[31mERR\x1B[0m",
108
- "\x1B[33mWRN\x1B[0m",
109
- "\x1B[34mINF\x1B[0m",
110
- "\x1B[36mDBG\x1B[0m",
111
- "\x1B[35mVRB\x1B[0m"
112
- ] : [
113
- "",
114
- // OFF
115
- "ERR",
116
- "WRN",
117
- "INF",
118
- "DBG",
119
- "VRB"
120
- ];
121
- const TAG_COLORS = [6, 2, 3, 4, 5, 1].map((i) => `\x1B[3${i};1m`);
122
- const defaultLoggingHandler = isTty ? (color, level, tag, fmt, args) => {
123
- console.log(BASE_FORMAT + fmt, (/* @__PURE__ */ new Date()).toISOString(), LEVEL_NAMES[level], TAG_COLORS[color], tag, ...args);
124
- } : (color, level, tag, fmt, args) => {
125
- console.log(BASE_FORMAT + fmt, (/* @__PURE__ */ new Date()).toISOString(), LEVEL_NAMES[level], tag, ...args);
126
- };
127
- const BUFFER_BASE64_URL_AVAILABLE = typeof Buffer.isEncoding === "function" && Buffer.isEncoding("base64url");
128
- const toBuffer = (buf) => Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);
129
- class NodePlatform {
130
- getDeviceModel() {
131
- return `Node.js/${process.version} (${os.type()} ${os.arch()})`;
132
- }
133
- getDefaultLogLevel() {
134
- const envLogLevel = Number.parseInt(process.env.MTCUTE_LOG_LEVEL ?? "");
135
- if (!Number.isNaN(envLogLevel)) {
136
- return envLogLevel;
137
- }
138
- return null;
139
- }
140
- // ITlPlatform
141
- utf8ByteLength(str) {
142
- return Buffer.byteLength(str, "utf8");
143
- }
144
- utf8Encode(str) {
145
- return Buffer.from(str, "utf8");
146
- }
147
- utf8Decode(buf) {
148
- return toBuffer(buf).toString("utf8");
149
- }
150
- hexEncode(buf) {
151
- return toBuffer(buf).toString("hex");
152
- }
153
- hexDecode(str) {
154
- return Buffer.from(str, "hex");
155
- }
156
- base64Encode(buf, url = false) {
157
- const nodeBuffer = toBuffer(buf);
158
- if (url && BUFFER_BASE64_URL_AVAILABLE) return nodeBuffer.toString("base64url");
159
- const str = nodeBuffer.toString("base64");
160
- if (url) return str.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
161
- return str;
162
- }
163
- base64Decode(string, url = false) {
164
- if (url && BUFFER_BASE64_URL_AVAILABLE) {
165
- return Buffer.from(string, "base64url");
166
- }
167
- if (url) {
168
- string = string.replace(/-/g, "+").replace(/_/g, "/");
169
- while (string.length % 4) string += "=";
170
- }
171
- return Buffer.from(string, "base64");
172
- }
173
- }
174
- NodePlatform.prototype.log = defaultLoggingHandler;
175
- NodePlatform.prototype.beforeExit = beforeExit;
176
- NodePlatform.prototype.normalizeFile = normalizeFile$1;
177
- function isBunFile(file) {
178
- return file instanceof Blob && "name" in file && file.name.length > 0;
179
- }
180
- async function normalizeFile(file) {
181
- if (typeof file === "string") {
182
- file = Bun.file(file);
183
- }
184
- if (isBunFile(file)) {
185
- return {
186
- file,
187
- fileName: file.name,
188
- fileSize: file.size
189
- };
190
- }
191
- if (file instanceof ReadStream) {
192
- const fileName = basename(file.path.toString());
193
- const fileSize = await stat(file.path.toString()).then((stat2) => stat2.size);
194
- return {
195
- file: Readable.toWeb(file),
196
- fileName,
197
- fileSize
198
- };
199
- }
200
- if (file instanceof Readable) {
201
- return {
202
- file: Readable.toWeb(file)
203
- };
204
- }
205
- return null;
206
- }
207
- class BunPlatform extends NodePlatform {
208
- getDeviceModel() {
209
- return `Bun/${Bun.version} (${os.type()} ${os.arch()})`;
210
- }
211
- }
212
- BunPlatform.prototype.normalizeFile = normalizeFile;
213
- class SqliteStorageDriver extends BaseSqliteStorageDriver {
214
- constructor(filename = ":memory:", params) {
215
- super();
216
- this.filename = filename;
217
- this.params = params;
218
- }
219
- _createDatabase() {
220
- const db = new Database(this.filename);
221
- if (!this.params?.disableWal) {
222
- db.exec("PRAGMA journal_mode = WAL;");
223
- }
224
- return db;
225
- }
226
- }
227
- class SqliteStorage extends BaseSqliteStorage {
228
- constructor(filename = ":memory:", params) {
229
- super(new SqliteStorageDriver(filename, params));
230
- this.filename = filename;
231
- this.params = params;
232
- }
233
- }
234
- class BunCryptoProvider extends BaseCryptoProvider {
235
- async initialize() {
236
- const wasmFile = require.resolve("@mtcute/wasm/mtcute.wasm");
237
- const wasm = await readFile(wasmFile);
238
- initSync(wasm);
239
- }
240
- createAesIge(key, iv) {
241
- return {
242
- encrypt(data) {
243
- return ige256Encrypt(data, key, iv);
244
- },
245
- decrypt(data) {
246
- return ige256Decrypt(data, key, iv);
247
- }
248
- };
249
- }
250
- createAesCtr(key, iv) {
251
- const ctx = createCtr256(key, iv);
252
- return {
253
- process: (data) => ctr256(ctx, data),
254
- close: () => freeCtr256(ctx)
255
- };
256
- }
257
- pbkdf2(password, salt, iterations, keylen = 64, algo = "sha512") {
258
- return new Promise(
259
- (resolve, reject) => pbkdf2(password, salt, iterations, keylen, algo, (err, buf) => err !== null ? reject(err) : resolve(buf))
260
- );
261
- }
262
- sha1(data) {
263
- const res = new Uint8Array(Bun.SHA1.byteLength);
264
- Bun.SHA1.hash(data, res);
265
- return res;
266
- }
267
- sha256(data) {
268
- const res = new Uint8Array(Bun.SHA256.byteLength);
269
- Bun.SHA256.hash(data, res);
270
- return res;
271
- }
272
- async hmacSha256(data, key) {
273
- const keyMaterial = await crypto.subtle.importKey(
274
- "raw",
275
- key,
276
- { name: "HMAC", hash: { name: "SHA-256" } },
277
- false,
278
- ["sign"]
279
- );
280
- const res = await crypto.subtle.sign({ name: "HMAC" }, keyMaterial, data);
281
- return new Uint8Array(res);
282
- }
283
- gzip(data, maxSize) {
284
- try {
285
- return deflateSync(data, {
286
- maxOutputLength: maxSize
287
- });
288
- } catch (e) {
289
- if (e.code === "ERR_BUFFER_TOO_LARGE") {
290
- return null;
291
- }
292
- throw e;
293
- }
294
- }
295
- gunzip(data) {
296
- return gunzipSync(data);
297
- }
298
- randomFill(buf) {
299
- crypto.getRandomValues(buf);
300
- }
301
- }
302
- class BaseTcpTransport extends EventEmitter {
303
- _currentDc = null;
304
- _state = TransportState.Idle;
305
- _socket = null;
306
- _crypto;
307
- log;
308
- packetCodecInitialized = false;
309
- _updateLogPrefix() {
310
- if (this._currentDc) {
311
- this.log.prefix = `[TCP:${this._currentDc.ipAddress}:${this._currentDc.port}] `;
312
- } else {
313
- this.log.prefix = "[TCP:disconnected] ";
314
- }
315
- }
316
- setup(crypto2, log) {
317
- this._crypto = crypto2;
318
- this.log = log.create("tcp");
319
- this._updateLogPrefix();
320
- }
321
- state() {
322
- return this._state;
323
- }
324
- currentDc() {
325
- return this._currentDc;
326
- }
327
- // eslint-disable-next-line unused-imports/no-unused-vars
328
- connect(dc, testMode) {
329
- if (this._state !== TransportState.Idle) {
330
- throw new MtcuteError("Transport is not IDLE");
331
- }
332
- if (!this.packetCodecInitialized) {
333
- this._packetCodec.setup?.(this._crypto, this.log);
334
- this._packetCodec.on("error", (err) => this.emit("error", err));
335
- this._packetCodec.on("packet", (buf) => this.emit("message", buf));
336
- this.packetCodecInitialized = true;
337
- }
338
- this._state = TransportState.Connecting;
339
- this._currentDc = dc;
340
- this._updateLogPrefix();
341
- this.log.debug("connecting to %j", dc);
342
- Bun.connect({
343
- hostname: dc.ipAddress,
344
- port: dc.port,
345
- socket: {
346
- open: this.handleConnect.bind(this),
347
- error: this.handleError.bind(this),
348
- data: (socket, data) => this._packetCodec.feed(data),
349
- close: this.close.bind(this),
350
- drain: this.handleDrained.bind(this)
351
- }
352
- }).catch((err) => {
353
- this.handleError(null, err);
354
- this.close();
355
- });
356
- }
357
- close() {
358
- if (this._state === TransportState.Idle) return;
359
- this.log.info("connection closed");
360
- this._state = TransportState.Idle;
361
- this._socket?.end();
362
- this._socket = null;
363
- this._currentDc = null;
364
- this._packetCodec.reset();
365
- this._sendOnceDrained = [];
366
- this.emit("close");
367
- }
368
- handleError(socket, error) {
369
- this.log.error("error: %s", error.stack);
370
- if (this.listenerCount("error") > 0) {
371
- this.emit("error", error);
372
- }
373
- }
374
- handleConnect(socket) {
375
- this._socket = socket;
376
- this.log.info("connected");
377
- Promise.resolve(this._packetCodec.tag()).then((initialMessage) => {
378
- if (initialMessage.length) {
379
- this._socket.write(initialMessage);
380
- this._state = TransportState.Ready;
381
- this.emit("ready");
382
- } else {
383
- this._state = TransportState.Ready;
384
- this.emit("ready");
385
- }
386
- }).catch((err) => {
387
- if (this.listenerCount("error") > 0) {
388
- this.emit("error", err);
389
- }
390
- });
391
- }
392
- async send(bytes) {
393
- const framed = await this._packetCodec.encode(bytes);
394
- if (this._state !== TransportState.Ready) {
395
- throw new MtcuteError("Transport is not READY");
396
- }
397
- const written = this._socket.write(framed);
398
- if (written < framed.length) {
399
- this._sendOnceDrained.push(framed.subarray(written));
400
- }
401
- }
402
- _sendOnceDrained = [];
403
- handleDrained() {
404
- while (this._sendOnceDrained.length) {
405
- const data = this._sendOnceDrained.shift();
406
- const written = this._socket.write(data);
407
- if (written < data.length) {
408
- this._sendOnceDrained.unshift(data.subarray(written));
409
- break;
410
- }
411
- }
412
- }
413
- }
414
- class TcpTransport extends BaseTcpTransport {
415
- _packetCodec = new IntermediatePacketCodec();
416
- }
417
- class BaseTelegramClient extends BaseTelegramClient$1 {
418
- constructor(opts) {
419
- if (!opts.platformless) setPlatform(new BunPlatform());
420
- super({
421
- crypto: new BunCryptoProvider(),
422
- transport: () => new TcpTransport(),
423
- ...opts,
424
- storage: typeof opts.storage === "string" ? new SqliteStorage(opts.storage) : opts.storage ?? new SqliteStorage("client.session")
425
- });
426
- }
427
- }
428
- class TelegramClient extends TelegramClient$1 {
429
- constructor(opts) {
430
- if ("client" in opts) {
431
- super(opts);
432
- return;
433
- }
434
- super({
435
- client: new BaseTelegramClient(opts),
436
- disableUpdates: opts.disableUpdates,
437
- skipConversationUpdates: opts.skipConversationUpdates,
438
- updates: opts.updates
439
- });
440
- }
441
- _rl;
442
- /**
443
- * Tiny wrapper over Node `readline` package
444
- * for simpler user input for `.start()` method.
445
- *
446
- * Associated `readline` interface is closed
447
- * after `start()` returns, or with the client.
448
- *
449
- * @param text Text of the question
450
- */
451
- input(text) {
452
- if (!this._rl) {
453
- this._rl = createInterface({
454
- input: process.stdin,
455
- output: process.stdout
456
- });
457
- }
458
- return new Promise((res) => this._rl?.question(text, res));
459
- }
460
- close() {
461
- this._rl?.close();
462
- return super.close();
463
- }
464
- start(params = {}) {
465
- if (!params.botToken) {
466
- if (!params.phone) params.phone = () => this.input("phone > ");
467
- if (!params.code) params.code = () => this.input("code > ");
468
- if (!params.password) {
469
- params.password = () => this.input("2fa password > ");
470
- }
471
- }
472
- return super.start(params).then((user) => {
473
- if (this._rl) {
474
- this._rl.close();
475
- delete this._rl;
476
- }
477
- return user;
478
- });
479
- }
480
- run(params, then) {
481
- if (typeof params === "function") {
482
- then = params;
483
- params = {};
484
- }
485
- this.start(params).then(then).catch((err) => this.emitError(err));
486
- }
487
- downloadToFile(filename, location, params) {
488
- return downloadToFile(this, filename, location, params);
489
- }
490
- downloadAsNodeStream(location, params) {
491
- return downloadAsNodeStream(this, location, params);
492
- }
493
- }
494
- let _registered = false;
495
- class TelegramWorker extends TelegramWorker$1 {
496
- registerWorker(handler) {
497
- if (!parentPort) {
498
- throw new Error("TelegramWorker must be created from a worker thread");
499
- }
500
- if (_registered) {
501
- throw new Error("TelegramWorker must be created only once");
502
- }
503
- _registered = true;
504
- const port = parentPort;
505
- const respond = port.postMessage.bind(port);
506
- parentPort.on("message", (message) => handler(message, respond));
507
- return respond;
508
- }
509
- }
510
- class TelegramWorkerPort extends TelegramWorkerPort$1 {
511
- constructor(options) {
512
- setPlatform(new BunPlatform());
513
- super(options);
514
- this.options = options;
515
- }
516
- connectToWorker(worker, handler) {
517
- if (!(worker instanceof Worker)) {
518
- throw new TypeError("Only worker_threads are supported");
519
- }
520
- const send = worker.postMessage.bind(worker);
521
- worker.on("message", handler);
522
- return [
523
- send,
524
- () => {
525
- worker.off("message", handler);
526
- }
527
- ];
528
- }
529
- }
11
+ import { SqliteStorageDriver } from "./sqlite/driver.js";
12
+ import { HttpProxyConnectionError, SocksProxyConnectionError } from "@fuman/net";
530
13
  export {
531
- BaseTcpTransport,
532
14
  BaseTelegramClient,
533
15
  BunCryptoProvider,
534
16
  BunPlatform,
17
+ HttpProxyConnectionError,
18
+ HttpProxyTcpTransport,
19
+ MtProxyTcpTransport,
20
+ SocksProxyConnectionError,
21
+ SocksProxyTcpTransport,
535
22
  SqliteStorage,
536
23
  SqliteStorageDriver,
537
24
  TcpTransport,
@@ -1,7 +1,6 @@
1
1
  import { unlinkSync } from "node:fs";
2
2
  import { FileLocation } from "@mtcute/core";
3
- import { downloadAsIterable, downloadAsStream } from "@mtcute/core/methods.js";
4
- import { Readable } from "node:stream";
3
+ import { downloadAsIterable } from "@mtcute/core/methods.js";
5
4
  async function downloadToFile(client, filename, location, params) {
6
5
  if (location instanceof FileLocation && ArrayBuffer.isView(location.location)) {
7
6
  await Bun.write(filename, location.location);
@@ -20,10 +19,6 @@ async function downloadToFile(client, filename, location, params) {
20
19
  }
21
20
  await output.end();
22
21
  }
23
- function downloadAsNodeStream(client, location, params) {
24
- return Readable.fromWeb(downloadAsStream(client, location, params));
25
- }
26
22
  export {
27
- downloadAsNodeStream,
28
23
  downloadToFile
29
24
  };
@@ -1,5 +1,5 @@
1
- import { Readable } from 'node:stream';
2
1
  import { FileDownloadLocation, FileDownloadParameters, ITelegramClient } from '@mtcute/core';
2
+ import { Readable } from 'node:stream';
3
3
  /**
4
4
  * Download a remote file as a Node.js Readable stream
5
5
  * (discouraged under Bun, since Web Streams are first-class).
@@ -0,0 +1,8 @@
1
+ import { Readable } from "node:stream";
2
+ import { downloadAsStream } from "@mtcute/core/methods.js";
3
+ function downloadAsNodeStream(client, location, params) {
4
+ return Readable.fromWeb(downloadAsStream(client, location, params));
5
+ }
6
+ export {
7
+ downloadAsNodeStream
8
+ };
package/methods.js CHANGED
@@ -1,4 +1,5 @@
1
- import { downloadAsNodeStream, downloadToFile } from "./chunks/es/BmtxbrWZ.js";
1
+ import { downloadToFile } from "./methods/download-file.js";
2
+ import { downloadAsNodeStream } from "./methods/download-node-stream.js";
2
3
  export * from "@mtcute/core/methods.js";
3
4
  export {
4
5
  downloadAsNodeStream,
package/package.json CHANGED
@@ -1,11 +1,19 @@
1
1
  {
2
2
  "name": "@mtcute/bun",
3
3
  "type": "module",
4
- "version": "0.17.0",
4
+ "version": "0.18.0",
5
5
  "description": "Meta-package for Bun",
6
- "author": "alina sireneva <alina@tei.su>",
7
6
  "license": "MIT",
8
- "sideEffects": false,
7
+ "dependencies": {
8
+ "@mtcute/core": "^0.18.0",
9
+ "@mtcute/html-parser": "^0.18.0",
10
+ "@mtcute/markdown-parser": "^0.18.0",
11
+ "@mtcute/wasm": "^0.18.0",
12
+ "@fuman/utils": "0.0.4",
13
+ "@fuman/bun": "0.0.4",
14
+ "@fuman/net": "0.0.4",
15
+ "@fuman/io": "0.0.4"
16
+ },
9
17
  "exports": {
10
18
  ".": {
11
19
  "import": {
@@ -38,16 +46,12 @@
38
46
  }
39
47
  }
40
48
  },
41
- "scripts": {},
42
- "dependencies": {
43
- "@mtcute/core": "^0.17.0",
44
- "@mtcute/html-parser": "^0.17.0",
45
- "@mtcute/markdown-parser": "^0.17.0",
46
- "@mtcute/wasm": "^0.17.0"
47
- },
49
+ "author": "alina sireneva <alina@tei.su>",
50
+ "sideEffects": false,
48
51
  "homepage": "https://mtcute.dev",
49
52
  "repository": {
50
53
  "type": "git",
51
- "url": "https://github.com/mtcute/mtcute"
52
- }
54
+ "url": "git+https://github.com/mtcute/mtcute.git"
55
+ },
56
+ "scripts": {}
53
57
  }
package/platform.d.ts CHANGED
@@ -1,6 +1,11 @@
1
- import { NodePlatform } from './common-internals-node/platform.js';
1
+ import { ICorePlatform } from '@mtcute/core';
2
+ import { beforeExit } from './utils/exit-hook.js';
3
+ import { defaultLoggingHandler } from './utils/logging.js';
2
4
  import { normalizeFile } from './utils/normalize-file.js';
3
- export declare class BunPlatform extends NodePlatform {
5
+ export declare class BunPlatform implements ICorePlatform {
6
+ log: typeof defaultLoggingHandler;
7
+ beforeExit: typeof beforeExit;
4
8
  normalizeFile: typeof normalizeFile;
5
9
  getDeviceModel(): string;
10
+ getDefaultLogLevel(): number | null;
6
11
  }
package/platform.js ADDED
@@ -0,0 +1,22 @@
1
+ import * as os from "node:os";
2
+ import { beforeExit } from "./utils/exit-hook.js";
3
+ import { defaultLoggingHandler } from "./utils/logging.js";
4
+ import { normalizeFile } from "./utils/normalize-file.js";
5
+ class BunPlatform {
6
+ getDeviceModel() {
7
+ return `Bun/${Bun.version} (${os.type()} ${os.arch()})`;
8
+ }
9
+ getDefaultLogLevel() {
10
+ const envLogLevel = Number.parseInt(process.env.MTCUTE_LOG_LEVEL ?? "");
11
+ if (!Number.isNaN(envLogLevel)) {
12
+ return envLogLevel;
13
+ }
14
+ return null;
15
+ }
16
+ }
17
+ BunPlatform.prototype.normalizeFile = normalizeFile;
18
+ BunPlatform.prototype.log = defaultLoggingHandler;
19
+ BunPlatform.prototype.beforeExit = beforeExit;
20
+ export {
21
+ BunPlatform
22
+ };
@@ -0,0 +1,19 @@
1
+ import { BaseSqliteStorageDriver } from "@mtcute/core";
2
+ import { Database } from "bun:sqlite";
3
+ class SqliteStorageDriver extends BaseSqliteStorageDriver {
4
+ constructor(filename = ":memory:", params) {
5
+ super();
6
+ this.filename = filename;
7
+ this.params = params;
8
+ }
9
+ _createDatabase() {
10
+ const db = new Database(this.filename);
11
+ if (!this.params?.disableWal) {
12
+ db.exec("PRAGMA journal_mode = WAL;");
13
+ }
14
+ return db;
15
+ }
16
+ }
17
+ export {
18
+ SqliteStorageDriver
19
+ };
package/sqlite/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { BaseSqliteStorage } from '@mtcute/core';
2
1
  import { SqliteStorageDriverOptions } from './driver.js';
2
+ import { BaseSqliteStorage } from '@mtcute/core';
3
3
  export { SqliteStorageDriver } from './driver.js';
4
4
  export declare class SqliteStorage extends BaseSqliteStorage {
5
5
  readonly filename: string;
@@ -0,0 +1,13 @@
1
+ import { BaseSqliteStorage } from "@mtcute/core";
2
+ import { SqliteStorageDriver } from "./driver.js";
3
+ class SqliteStorage extends BaseSqliteStorage {
4
+ constructor(filename = ":memory:", params) {
5
+ super(new SqliteStorageDriver(filename, params));
6
+ this.filename = filename;
7
+ this.params = params;
8
+ }
9
+ }
10
+ export {
11
+ SqliteStorage,
12
+ SqliteStorageDriver
13
+ };
@@ -0,0 +1,77 @@
1
+ import { pbkdf2 } from "node:crypto";
2
+ import { readFile } from "node:fs/promises";
3
+ import { deflateSync, gunzipSync } from "node:zlib";
4
+ import { u8 } from "@fuman/utils";
5
+ import { BaseCryptoProvider } from "@mtcute/core/utils.js";
6
+ import { initSync, ige256Decrypt, ige256Encrypt, createCtr256, freeCtr256, ctr256 } from "@mtcute/wasm";
7
+ class BunCryptoProvider extends BaseCryptoProvider {
8
+ async initialize() {
9
+ const wasmFile = require.resolve("@mtcute/wasm/mtcute.wasm");
10
+ const wasm = await readFile(wasmFile);
11
+ initSync(wasm);
12
+ }
13
+ createAesIge(key, iv) {
14
+ return {
15
+ encrypt(data) {
16
+ return ige256Encrypt(data, key, iv);
17
+ },
18
+ decrypt(data) {
19
+ return ige256Decrypt(data, key, iv);
20
+ }
21
+ };
22
+ }
23
+ createAesCtr(key, iv) {
24
+ const ctx = createCtr256(key, iv);
25
+ return {
26
+ process: (data) => ctr256(ctx, data),
27
+ close: () => freeCtr256(ctx)
28
+ };
29
+ }
30
+ pbkdf2(password, salt, iterations, keylen = 64, algo = "sha512") {
31
+ return new Promise(
32
+ (resolve, reject) => pbkdf2(password, salt, iterations, keylen, algo, (err, buf) => err !== null ? reject(err) : resolve(buf))
33
+ );
34
+ }
35
+ sha1(data) {
36
+ const res = u8.alloc(Bun.SHA1.byteLength);
37
+ Bun.SHA1.hash(data, res);
38
+ return res;
39
+ }
40
+ sha256(data) {
41
+ const res = u8.alloc(Bun.SHA256.byteLength);
42
+ Bun.SHA256.hash(data, res);
43
+ return res;
44
+ }
45
+ async hmacSha256(data, key) {
46
+ const keyMaterial = await crypto.subtle.importKey(
47
+ "raw",
48
+ key,
49
+ { name: "HMAC", hash: { name: "SHA-256" } },
50
+ false,
51
+ ["sign"]
52
+ );
53
+ const res = await crypto.subtle.sign({ name: "HMAC" }, keyMaterial, data);
54
+ return new Uint8Array(res);
55
+ }
56
+ gzip(data, maxSize) {
57
+ try {
58
+ return deflateSync(data, {
59
+ maxOutputLength: maxSize
60
+ });
61
+ } catch (e) {
62
+ if (e.code === "ERR_BUFFER_TOO_LARGE") {
63
+ return null;
64
+ }
65
+ throw e;
66
+ }
67
+ }
68
+ gunzip(data) {
69
+ return gunzipSync(data);
70
+ }
71
+ randomFill(buf) {
72
+ crypto.getRandomValues(buf);
73
+ }
74
+ }
75
+ export {
76
+ BunCryptoProvider
77
+ };
@@ -0,0 +1,41 @@
1
+ let installed = false;
2
+ let handled = false;
3
+ const callbacks = /* @__PURE__ */ new Set();
4
+ const myHandlers = /* @__PURE__ */ new Map();
5
+ function register(shouldManuallyExit, signal, event) {
6
+ function eventHandler() {
7
+ if (handled) {
8
+ return;
9
+ }
10
+ handled = true;
11
+ for (const callback of callbacks) {
12
+ callback();
13
+ }
14
+ for (const [event2, handler] of myHandlers) {
15
+ process.off(event2, handler);
16
+ }
17
+ if (shouldManuallyExit) {
18
+ process.kill(process.pid, signal);
19
+ }
20
+ }
21
+ process.on(event, eventHandler);
22
+ myHandlers.set(event, eventHandler);
23
+ }
24
+ function beforeExit(fn) {
25
+ if (typeof process === "undefined") return () => {
26
+ };
27
+ if (!installed) {
28
+ installed = true;
29
+ register(true, 0, "beforeExit");
30
+ register(true, 2, "SIGINT");
31
+ register(true, 15, "SIGTERM");
32
+ register(false, 15, "exit");
33
+ }
34
+ callbacks.add(fn);
35
+ return () => {
36
+ callbacks.delete(fn);
37
+ };
38
+ }
39
+ export {
40
+ beforeExit
41
+ };
@@ -0,0 +1,28 @@
1
+ const isTty = typeof process === "object" && Boolean(process.stdout?.isTTY);
2
+ const BASE_FORMAT = isTty ? "%s [%s] [%s%s\x1B[0m] " : "%s [%s] [%s] ";
3
+ const LEVEL_NAMES = isTty ? [
4
+ "",
5
+ // OFF
6
+ "\x1B[31mERR\x1B[0m",
7
+ "\x1B[33mWRN\x1B[0m",
8
+ "\x1B[34mINF\x1B[0m",
9
+ "\x1B[36mDBG\x1B[0m",
10
+ "\x1B[35mVRB\x1B[0m"
11
+ ] : [
12
+ "",
13
+ // OFF
14
+ "ERR",
15
+ "WRN",
16
+ "INF",
17
+ "DBG",
18
+ "VRB"
19
+ ];
20
+ const TAG_COLORS = [6, 2, 3, 4, 5, 1].map((i) => `\x1B[3${i};1m`);
21
+ const defaultLoggingHandler = isTty ? (color, level, tag, fmt, args) => {
22
+ console.log(BASE_FORMAT + fmt, (/* @__PURE__ */ new Date()).toISOString(), LEVEL_NAMES[level], TAG_COLORS[color], tag, ...args);
23
+ } : (color, level, tag, fmt, args) => {
24
+ console.log(BASE_FORMAT + fmt, (/* @__PURE__ */ new Date()).toISOString(), LEVEL_NAMES[level], tag, ...args);
25
+ };
26
+ export {
27
+ defaultLoggingHandler
28
+ };
@@ -0,0 +1,37 @@
1
+ import { ReadStream } from "node:fs";
2
+ import { stat } from "node:fs/promises";
3
+ import { basename } from "node:path";
4
+ import { Readable } from "node:stream";
5
+ function isBunFile(file) {
6
+ return file instanceof Blob && "name" in file && file.name.length > 0;
7
+ }
8
+ async function normalizeFile(file) {
9
+ if (typeof file === "string") {
10
+ file = Bun.file(file);
11
+ }
12
+ if (isBunFile(file)) {
13
+ return {
14
+ file,
15
+ fileName: file.name,
16
+ fileSize: file.size
17
+ };
18
+ }
19
+ if (file instanceof ReadStream) {
20
+ const fileName = basename(file.path.toString());
21
+ const fileSize = await stat(file.path.toString()).then((stat2) => stat2.size);
22
+ return {
23
+ file: Readable.toWeb(file),
24
+ fileName,
25
+ fileSize
26
+ };
27
+ }
28
+ if (file instanceof Readable) {
29
+ return {
30
+ file: Readable.toWeb(file)
31
+ };
32
+ }
33
+ return null;
34
+ }
35
+ export {
36
+ normalizeFile
37
+ };
@@ -0,0 +1,27 @@
1
+ import { HttpProxySettings as FumanHttpProxySettings, ITcpConnection, SocksProxySettings, TcpEndpoint } from '@fuman/net';
2
+ import { BasicDcOption } from '@mtcute/core/utils.js';
3
+ import { BaseMtProxyTransport, IntermediatePacketCodec, ITelegramConnection, TelegramTransport } from '@mtcute/core';
4
+ export type { SocksProxySettings } from '@fuman/net';
5
+ export { HttpProxyConnectionError, SocksProxyConnectionError } from '@fuman/net';
6
+ export type { MtProxySettings } from '@mtcute/core';
7
+ export interface HttpProxySettings extends FumanHttpProxySettings {
8
+ /**
9
+ * Whether this is a HTTPS proxy (by default it is regular HTTP).
10
+ */
11
+ tls?: boolean;
12
+ }
13
+ export declare class HttpProxyTcpTransport implements TelegramTransport {
14
+ readonly proxy: HttpProxySettings;
15
+ constructor(proxy: HttpProxySettings);
16
+ connect(dc: BasicDcOption): Promise<ITelegramConnection>;
17
+ packetCodec(): IntermediatePacketCodec;
18
+ }
19
+ export declare class SocksProxyTcpTransport implements TelegramTransport {
20
+ readonly proxy: SocksProxySettings;
21
+ constructor(proxy: SocksProxySettings);
22
+ connect(dc: BasicDcOption): Promise<ITelegramConnection>;
23
+ packetCodec(): IntermediatePacketCodec;
24
+ }
25
+ export declare class MtProxyTcpTransport extends BaseMtProxyTransport {
26
+ _connectTcp(endpoint: TcpEndpoint): Promise<ITcpConnection>;
27
+ }
@@ -0,0 +1,62 @@
1
+ import { connectTls, connectTcp } from "@fuman/bun";
2
+ import { performHttpProxyHandshake, performSocksHandshake } from "@fuman/net";
3
+ import { HttpProxyConnectionError, SocksProxyConnectionError } from "@fuman/net";
4
+ import { IntermediatePacketCodec, BaseMtProxyTransport } from "@mtcute/core";
5
+ class HttpProxyTcpTransport {
6
+ constructor(proxy) {
7
+ this.proxy = proxy;
8
+ }
9
+ async connect(dc) {
10
+ let conn;
11
+ if (this.proxy.tls) {
12
+ conn = await connectTls({
13
+ address: this.proxy.host,
14
+ port: this.proxy.port
15
+ });
16
+ } else {
17
+ conn = await connectTcp({
18
+ address: this.proxy.host,
19
+ port: this.proxy.port
20
+ });
21
+ }
22
+ await performHttpProxyHandshake(conn, conn, this.proxy, {
23
+ address: dc.ipAddress,
24
+ port: dc.port
25
+ });
26
+ return conn;
27
+ }
28
+ packetCodec() {
29
+ return new IntermediatePacketCodec();
30
+ }
31
+ }
32
+ class SocksProxyTcpTransport {
33
+ constructor(proxy) {
34
+ this.proxy = proxy;
35
+ }
36
+ async connect(dc) {
37
+ const conn = await connectTcp({
38
+ address: this.proxy.host,
39
+ port: this.proxy.port
40
+ });
41
+ await performSocksHandshake(conn, conn, this.proxy, {
42
+ address: dc.ipAddress,
43
+ port: dc.port
44
+ });
45
+ return conn;
46
+ }
47
+ packetCodec() {
48
+ return new IntermediatePacketCodec();
49
+ }
50
+ }
51
+ class MtProxyTcpTransport extends BaseMtProxyTransport {
52
+ async _connectTcp(endpoint) {
53
+ return connectTcp(endpoint);
54
+ }
55
+ }
56
+ export {
57
+ HttpProxyConnectionError,
58
+ HttpProxyTcpTransport,
59
+ MtProxyTcpTransport,
60
+ SocksProxyConnectionError,
61
+ SocksProxyTcpTransport
62
+ };
package/utils/tcp.d.ts CHANGED
@@ -1,31 +1,7 @@
1
- import { default as EventEmitter } from 'events';
2
- import { Socket } from 'bun';
3
- import { IPacketCodec, ITelegramTransport, IntermediatePacketCodec, TransportState } from '@mtcute/core';
4
- import { BasicDcOption, ICryptoProvider, Logger } from '@mtcute/core/utils.js';
5
- /**
6
- * Base for TCP transports.
7
- * Subclasses must provide packet codec in `_packetCodec` property
8
- */
9
- export declare abstract class BaseTcpTransport extends EventEmitter implements ITelegramTransport {
10
- protected _currentDc: BasicDcOption | null;
11
- protected _state: TransportState;
12
- protected _socket: Socket | null;
13
- abstract _packetCodec: IPacketCodec;
14
- protected _crypto: ICryptoProvider;
15
- protected log: Logger;
16
- packetCodecInitialized: boolean;
17
- private _updateLogPrefix;
18
- setup(crypto: ICryptoProvider, log: Logger): void;
19
- state(): TransportState;
20
- currentDc(): BasicDcOption | null;
21
- connect(dc: BasicDcOption, testMode: boolean): void;
22
- close(): void;
23
- handleError(socket: unknown, error: Error): void;
24
- handleConnect(socket: Socket): void;
25
- send(bytes: Uint8Array): Promise<void>;
26
- private _sendOnceDrained;
27
- private handleDrained;
28
- }
29
- export declare class TcpTransport extends BaseTcpTransport {
30
- _packetCodec: IntermediatePacketCodec;
1
+ import { ITcpConnection } from '@fuman/net';
2
+ import { BasicDcOption } from '@mtcute/core/utils.js';
3
+ import { IntermediatePacketCodec, TelegramTransport } from '@mtcute/core';
4
+ export declare class TcpTransport implements TelegramTransport {
5
+ connect(dc: BasicDcOption): Promise<ITcpConnection>;
6
+ packetCodec(): IntermediatePacketCodec;
31
7
  }
package/utils/tcp.js ADDED
@@ -0,0 +1,13 @@
1
+ import { connectTcp } from "@fuman/bun";
2
+ import { IntermediatePacketCodec } from "@mtcute/core";
3
+ class TcpTransport {
4
+ connect(dc) {
5
+ return connectTcp({ address: dc.ipAddress, port: dc.port });
6
+ }
7
+ packetCodec() {
8
+ return new IntermediatePacketCodec();
9
+ }
10
+ }
11
+ export {
12
+ TcpTransport
13
+ };
package/worker.d.ts CHANGED
@@ -1,10 +1,12 @@
1
- import { ClientMessageHandler, RespondFn, SendFn, SomeWorker, TelegramWorkerOptions, TelegramWorkerPortOptions, WorkerCustomMethods, WorkerMessageHandler, TelegramWorker as TelegramWorkerBase, TelegramWorkerPort as TelegramWorkerPortBase } from '@mtcute/core/worker.js';
2
- export type { TelegramWorkerOptions, TelegramWorkerPortOptions, WorkerCustomMethods };
1
+ import { ClientMessageHandler, RespondFn, SendFn, SomeWorker, TelegramWorkerOptions, WorkerCustomMethods, WorkerMessageHandler, TelegramWorker as TelegramWorkerBase, TelegramWorkerPort as TelegramWorkerPortBase } from '@mtcute/core/worker.js';
2
+ export type { TelegramWorkerOptions, WorkerCustomMethods };
3
+ export interface TelegramWorkerPortOptions {
4
+ worker: SomeWorker;
5
+ }
3
6
  export declare class TelegramWorker<T extends WorkerCustomMethods> extends TelegramWorkerBase<T> {
4
7
  registerWorker(handler: WorkerMessageHandler): RespondFn;
5
8
  }
6
9
  export declare class TelegramWorkerPort<T extends WorkerCustomMethods> extends TelegramWorkerPortBase<T> {
7
- readonly options: TelegramWorkerPortOptions;
8
10
  constructor(options: TelegramWorkerPortOptions);
9
11
  connectToWorker(worker: SomeWorker, handler: ClientMessageHandler): [SendFn, () => void];
10
12
  }
package/worker.js ADDED
@@ -0,0 +1,44 @@
1
+ import { parentPort, Worker } from "node:worker_threads";
2
+ import { TelegramWorker as TelegramWorker$1, TelegramWorkerPort as TelegramWorkerPort$1 } from "@mtcute/core/worker.js";
3
+ import { BunPlatform } from "./platform.js";
4
+ let _registered = false;
5
+ class TelegramWorker extends TelegramWorker$1 {
6
+ registerWorker(handler) {
7
+ if (!parentPort) {
8
+ throw new Error("TelegramWorker must be created from a worker thread");
9
+ }
10
+ if (_registered) {
11
+ throw new Error("TelegramWorker must be created only once");
12
+ }
13
+ _registered = true;
14
+ const port = parentPort;
15
+ const respond = port.postMessage.bind(port);
16
+ parentPort.on("message", (message) => handler(message, respond));
17
+ return respond;
18
+ }
19
+ }
20
+ class TelegramWorkerPort extends TelegramWorkerPort$1 {
21
+ constructor(options) {
22
+ super({
23
+ worker: options.worker,
24
+ platform: new BunPlatform()
25
+ });
26
+ }
27
+ connectToWorker(worker, handler) {
28
+ if (!(worker instanceof Worker)) {
29
+ throw new TypeError("Only worker_threads are supported");
30
+ }
31
+ const send = worker.postMessage.bind(worker);
32
+ worker.on("message", handler);
33
+ return [
34
+ send,
35
+ () => {
36
+ worker.off("message", handler);
37
+ }
38
+ ];
39
+ }
40
+ }
41
+ export {
42
+ TelegramWorker,
43
+ TelegramWorkerPort
44
+ };
@@ -1,18 +0,0 @@
1
- import { ICorePlatform } from '@mtcute/core/platform.js';
2
- import { normalizeFile } from '../utils/normalize-file.js';
3
- import { beforeExit } from './exit-hook.js';
4
- import { defaultLoggingHandler } from './logging.js';
5
- export declare class NodePlatform implements ICorePlatform {
6
- log: typeof defaultLoggingHandler;
7
- beforeExit: typeof beforeExit;
8
- normalizeFile: typeof normalizeFile;
9
- getDeviceModel(): string;
10
- getDefaultLogLevel(): number | null;
11
- utf8ByteLength(str: string): number;
12
- utf8Encode(str: string): Uint8Array;
13
- utf8Decode(buf: Uint8Array): string;
14
- hexEncode(buf: Uint8Array): string;
15
- hexDecode(str: string): Uint8Array;
16
- base64Encode(buf: Uint8Array, url?: boolean): string;
17
- base64Decode(string: string, url?: boolean): Uint8Array;
18
- }
package/index.d.cts DELETED
@@ -1,9 +0,0 @@
1
- export * from './client.js';
2
- export * from './platform.js';
3
- export * from './sqlite/index.js';
4
- export * from './utils/crypto.js';
5
- export * from './utils/tcp.js';
6
- export * from './worker.js';
7
- export * from '@mtcute/core';
8
- export * from '@mtcute/html-parser';
9
- export * from '@mtcute/markdown-parser';
package/methods.d.cts DELETED
@@ -1,3 +0,0 @@
1
- export { downloadToFile } from './methods/download-file.js';
2
- export { downloadAsNodeStream } from './methods/download-node-stream.js';
3
- export * from '@mtcute/core/methods.js';
package/utils.d.cts DELETED
@@ -1 +0,0 @@
1
- export * from '@mtcute/core/utils.js';
File without changes
File without changes