@mtkruto/node 0.0.910 → 0.0.921

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.
Files changed (51) hide show
  1. package/esm/client/1_client_abstract.d.ts +2 -1
  2. package/esm/client/1_client_abstract.js +9 -3
  3. package/esm/client/3_client.d.ts +4 -2
  4. package/esm/client/3_client.js +150 -76
  5. package/esm/constants.d.ts +1 -1
  6. package/esm/constants.js +1 -1
  7. package/esm/deps.d.ts +1 -2
  8. package/esm/deps.js +0 -1
  9. package/esm/types/!0_file_id.d.ts +6 -6
  10. package/esm/types/!0_file_id.js +11 -58
  11. package/esm/types/0_chat_photo.d.ts +1 -0
  12. package/esm/types/0_chat_photo.js +4 -2
  13. package/esm/types/0_thumbnail.d.ts +9 -0
  14. package/esm/types/0_thumbnail.js +9 -0
  15. package/esm/types/1_photo.d.ts +11 -0
  16. package/esm/types/1_photo.js +49 -0
  17. package/esm/types/3_message.d.ts +2 -0
  18. package/esm/types/3_message.js +8 -3
  19. package/esm/utilities/0_base64.d.ts +2 -0
  20. package/esm/utilities/0_base64.js +9 -0
  21. package/esm/utilities/0_rle.d.ts +2 -0
  22. package/esm/utilities/0_rle.js +49 -0
  23. package/esm/utilities/0_rle_test.d.ts +1 -0
  24. package/package.json +1 -1
  25. package/script/client/1_client_abstract.d.ts +2 -1
  26. package/script/client/1_client_abstract.js +9 -3
  27. package/script/client/3_client.d.ts +4 -2
  28. package/script/client/3_client.js +149 -75
  29. package/script/constants.d.ts +1 -1
  30. package/script/constants.js +1 -1
  31. package/script/deps.d.ts +1 -2
  32. package/script/deps.js +1 -3
  33. package/script/types/!0_file_id.d.ts +6 -6
  34. package/script/types/!0_file_id.js +11 -58
  35. package/script/types/0_chat_photo.d.ts +1 -0
  36. package/script/types/0_chat_photo.js +4 -2
  37. package/script/types/0_thumbnail.d.ts +9 -0
  38. package/script/types/0_thumbnail.js +13 -0
  39. package/script/types/1_photo.d.ts +11 -0
  40. package/script/types/1_photo.js +76 -0
  41. package/script/types/3_message.d.ts +2 -0
  42. package/script/types/3_message.js +8 -3
  43. package/script/utilities/0_base64.d.ts +2 -0
  44. package/script/utilities/0_base64.js +14 -0
  45. package/script/utilities/0_rle.d.ts +2 -0
  46. package/script/utilities/0_rle.js +54 -0
  47. package/script/utilities/0_rle_test.d.ts +1 -0
  48. package/esm/deps/deno.land/x/q@v0.0.1/mod.d.ts +0 -6
  49. package/esm/deps/deno.land/x/q@v0.0.1/mod.js +0 -71
  50. package/script/deps/deno.land/x/q@v0.0.1/mod.d.ts +0 -6
  51. package/script/deps/deno.land/x/q@v0.0.1/mod.js +0 -75
@@ -4,12 +4,13 @@ import { Transport } from "../transport/0_transport.js";
4
4
  import { DC } from "../transport/2_transport_provider.js";
5
5
  export declare abstract class ClientAbstract {
6
6
  protected transportProvider: import("../transport/2_transport_provider.js").TransportProvider;
7
+ protected readonly cdn: boolean;
7
8
  protected connection: Connection;
8
9
  protected transport: Transport;
9
10
  private _dcId;
10
11
  private _initialDc;
11
12
  get initialDc(): DC;
12
- constructor(transportProvider?: import("../transport/2_transport_provider.js").TransportProvider);
13
+ constructor(transportProvider?: import("../transport/2_transport_provider.js").TransportProvider, cdn?: boolean);
13
14
  get dcId(): number;
14
15
  setDc(dc: DC): MaybePromise<void>;
15
16
  get connected(): boolean;
@@ -5,13 +5,19 @@ export class ClientAbstract {
5
5
  get initialDc() {
6
6
  return this._initialDc;
7
7
  }
8
- constructor(transportProvider = defaultTransportProvider({ initialDc: DEFAULT_INITIAL_DC })) {
8
+ constructor(transportProvider = defaultTransportProvider({ initialDc: DEFAULT_INITIAL_DC }), cdn = false) {
9
9
  Object.defineProperty(this, "transportProvider", {
10
10
  enumerable: true,
11
11
  configurable: true,
12
12
  writable: true,
13
13
  value: transportProvider
14
14
  });
15
+ Object.defineProperty(this, "cdn", {
16
+ enumerable: true,
17
+ configurable: true,
18
+ writable: true,
19
+ value: cdn
20
+ });
15
21
  Object.defineProperty(this, "connection", {
16
22
  enumerable: true,
17
23
  configurable: true,
@@ -38,7 +44,7 @@ export class ClientAbstract {
38
44
  });
39
45
  const { initialDc, createTransport } = transportProvider;
40
46
  this._initialDc = initialDc;
41
- const { connection, transport, dcId } = createTransport({ cdn: false });
47
+ const { connection, transport, dcId } = createTransport({ cdn: this.cdn });
42
48
  this.connection = connection;
43
49
  this.transport = transport;
44
50
  this._dcId = dcId;
@@ -48,7 +54,7 @@ export class ClientAbstract {
48
54
  }
49
55
  // MaybePromise since `Client` has to deal with `Storage.set()`
50
56
  setDc(dc) {
51
- const { connection, transport, dcId } = this.transportProvider.createTransport({ dc, cdn: false });
57
+ const { connection, transport, dcId } = this.transportProvider.createTransport({ dc, cdn: this.cdn });
52
58
  this.connection = connection;
53
59
  this.transport = transport;
54
60
  this._dcId = dcId;
@@ -83,7 +83,7 @@ export declare class Client extends ClientAbstract {
83
83
  * @param apiHash App's API hash from [my.telegram.org/apps](https://my.telegram.org/apps). Default to empty string (unset).
84
84
  * @param params Other parameters.
85
85
  */
86
- constructor(storage?: Storage, apiId?: number, apiHash?: string, params?: ClientParams);
86
+ constructor(storage?: Storage, apiId?: number, apiHash?: string, params?: ClientParams, cdn?: boolean);
87
87
  private storageInited;
88
88
  /**
89
89
  * Sets the DC and resets the auth key stored in the session provider
@@ -118,7 +118,6 @@ export declare class Client extends ClientAbstract {
118
118
  * [2]: https://core.telegram.org/method/updates.getState
119
119
  */
120
120
  authorize(params: string | types.AuthExportedAuthorization | AuthorizeUserParams): Promise<void>;
121
- private messageProcessQueue;
122
121
  private receiveLoop;
123
122
  private pingLoop;
124
123
  /**
@@ -138,6 +137,7 @@ export declare class Client extends ClientAbstract {
138
137
  private updateApplicationMutex;
139
138
  private applyUpdateNoGap;
140
139
  private applyUpdate;
140
+ private updateProcessLock;
141
141
  private processUpdates;
142
142
  private setUpdateStateDate;
143
143
  private getLocalState;
@@ -162,4 +162,6 @@ export declare class Client extends ClientAbstract {
162
162
  }): Promise<Omit<Message, "replyToMessage">>;
163
163
  getMessages(chatId: number | string, messageIds: number[]): Promise<Omit<Message, "replyToMessage">[]>;
164
164
  getMessage(chatId: number | string, messageId: number): Promise<Omit<Message, "replyToMessage"> | null>;
165
+ private downloadInner;
166
+ download(fileId_: string): Promise<AsyncGenerator<Uint8Array, void, unknown>>;
165
167
  }
@@ -1,4 +1,4 @@
1
- import { debug, gunzip, Mutex, queue } from "../deps.js";
1
+ import { debug, gunzip, Mutex } from "../deps.js";
2
2
  import { ackThreshold, CHANNEL_DIFFERENCE_LIMIT_BOT, CHANNEL_DIFFERENCE_LIMIT_USER, DEFAULT_APP_VERSION, DEFAULT_DEVICE_MODEL, DEFAULT_LANG_CODE, DEFAULT_LANG_PACK, DEFAULT_SYSTEM_LANG_CODE, DEFAULT_SYSTEM_VERSION, LAYER, MAX_CHANNEL_ID, MAX_CHAT_ID, USERNAME_TTL, ZERO_CHANNEL_ID } from "../constants.js";
3
3
  import { bigIntFromBuffer, getRandomBigInt, getRandomId } from "../utilities/0_bigint.js";
4
4
  import { UNREACHABLE } from "../utilities/0_control.js";
@@ -11,6 +11,7 @@ import { RPCResult } from "../tl/5_rpc_result.js";
11
11
  import { Message as Message_ } from "../tl/6_message.js"; // MTProto API message
12
12
  import { MessageContainer } from "../tl/7_message_container.js";
13
13
  import { StorageMemory } from "../storage/1_storage_memory.js";
14
+ import { FileID, FileType, ThumbnailSource } from "../types/!0_file_id.js";
14
15
  import { messageEntityToTlObject } from "../types/0_message_entity.js";
15
16
  import { replyKeyboardRemoveToTlObject } from "../types/0_reply_keyboard_remove.js";
16
17
  import { forceReplyToTlObject } from "../types/0_force_reply.js";
@@ -44,8 +45,8 @@ export class Client extends ClientAbstract {
44
45
  * @param apiHash App's API hash from [my.telegram.org/apps](https://my.telegram.org/apps). Default to empty string (unset).
45
46
  * @param params Other parameters.
46
47
  */
47
- constructor(storage = new StorageMemory(), apiId = 0, apiHash = "", params) {
48
- super(params?.transportProvider);
48
+ constructor(storage = new StorageMemory(), apiId = 0, apiHash = "", params, cdn = false) {
49
+ super(params?.transportProvider, cdn);
49
50
  Object.defineProperty(this, "storage", {
50
51
  enumerable: true,
51
52
  configurable: true,
@@ -154,68 +155,13 @@ export class Client extends ClientAbstract {
154
155
  writable: true,
155
156
  value: false
156
157
  });
157
- Object.defineProperty(this, "messageProcessQueue", {
158
+ Object.defineProperty(this, "updateApplicationMutex", {
158
159
  enumerable: true,
159
160
  configurable: true,
160
161
  writable: true,
161
- value: queue(async (message) => {
162
- let body = message.body;
163
- if (body instanceof types.GZIPPacked) {
164
- body = new TLReader(gunzip(body.packedData)).readObject();
165
- }
166
- dRecv("received %s", body.constructor.name);
167
- if (body instanceof types.Updates || body instanceof types.TypeUpdate) {
168
- await this.processUpdates(body);
169
- }
170
- else if (message.body instanceof RPCResult) {
171
- let result = message.body.result;
172
- if (result instanceof types.GZIPPacked) {
173
- result = new TLReader(gunzip(result.packedData)).readObject();
174
- }
175
- if (result instanceof types.RPCError) {
176
- dRecv("RPCResult: %d %s", result.errorCode, result.errorMessage);
177
- }
178
- else {
179
- dRecv("RPCResult: %s", result.constructor.name);
180
- }
181
- if (result instanceof types.Updates || result instanceof types.TypeUpdate) {
182
- await this.processUpdates(result);
183
- }
184
- else {
185
- await this.processResult(result);
186
- }
187
- const promise = this.promises.get(message.body.messageId);
188
- if (promise) {
189
- if (result instanceof types.RPCError) {
190
- promise.reject(result);
191
- }
192
- else {
193
- promise.resolve(result);
194
- }
195
- this.promises.delete(message.body.messageId);
196
- }
197
- }
198
- else if (message.body instanceof types.Pong) {
199
- const promise = this.promises.get(message.body.msgId);
200
- if (promise) {
201
- promise.resolve(message.body);
202
- this.promises.delete(message.body.msgId);
203
- }
204
- }
205
- else if (message.body instanceof types.BadMsgNotification || message.body instanceof types.BadServerSalt) {
206
- if (message.body instanceof types.BadServerSalt) {
207
- this.state.salt = message.body.newServerSalt;
208
- }
209
- const promise = this.promises.get(message.body.badMsgId);
210
- if (promise) {
211
- promise.resolve(message.body);
212
- this.promises.delete(message.body.badMsgId);
213
- }
214
- }
215
- this.toAcknowledge.add(message.id);
216
- }, 2)
162
+ value: new Mutex()
217
163
  });
218
- Object.defineProperty(this, "updateApplicationMutex", {
164
+ Object.defineProperty(this, "updateProcessLock", {
219
165
  enumerable: true,
220
166
  configurable: true,
221
167
  writable: true,
@@ -518,7 +464,64 @@ export class Client extends ClientAbstract {
518
464
  }
519
465
  const messages = decrypted instanceof MessageContainer ? decrypted.messages : [decrypted];
520
466
  for (const message of messages) {
521
- this.messageProcessQueue.push(message);
467
+ let body = message.body;
468
+ if (body instanceof types.GZIPPacked) {
469
+ body = new TLReader(gunzip(body.packedData)).readObject();
470
+ }
471
+ dRecv("received %s", body.constructor.name);
472
+ if (body instanceof types.Updates || body instanceof types.TypeUpdate) {
473
+ this.processUpdates(body);
474
+ }
475
+ else if (message.body instanceof RPCResult) {
476
+ let result = message.body.result;
477
+ if (result instanceof types.GZIPPacked) {
478
+ result = new TLReader(gunzip(result.packedData)).readObject();
479
+ }
480
+ if (result instanceof types.RPCError) {
481
+ dRecv("RPCResult: %d %s", result.errorCode, result.errorMessage);
482
+ }
483
+ else {
484
+ dRecv("RPCResult: %s", result.constructor.name);
485
+ }
486
+ const messageId = message.body.messageId;
487
+ const resolvePromise = () => {
488
+ const promise = this.promises.get(messageId);
489
+ if (promise) {
490
+ if (result instanceof types.RPCError) {
491
+ promise.reject(result);
492
+ }
493
+ else {
494
+ promise.resolve(result);
495
+ }
496
+ this.promises.delete(messageId);
497
+ }
498
+ };
499
+ if (result instanceof types.Updates || result instanceof types.TypeUpdate) {
500
+ this.processUpdates(result).then(resolvePromise);
501
+ }
502
+ else {
503
+ await this.processResult(result);
504
+ resolvePromise();
505
+ }
506
+ }
507
+ else if (message.body instanceof types.Pong) {
508
+ const promise = this.promises.get(message.body.msgId);
509
+ if (promise) {
510
+ promise.resolve(message.body);
511
+ this.promises.delete(message.body.msgId);
512
+ }
513
+ }
514
+ else if (message.body instanceof types.BadMsgNotification || message.body instanceof types.BadServerSalt) {
515
+ if (message.body instanceof types.BadServerSalt) {
516
+ this.state.salt = message.body.newServerSalt;
517
+ }
518
+ const promise = this.promises.get(message.body.badMsgId);
519
+ if (promise) {
520
+ promise.resolve(message.body);
521
+ this.promises.delete(message.body.badMsgId);
522
+ }
523
+ }
524
+ this.toAcknowledge.add(message.id);
522
525
  }
523
526
  }
524
527
  }
@@ -611,18 +614,20 @@ export class Client extends ClientAbstract {
611
614
  (update instanceof types.UpdateShortMessage) ||
612
615
  (update instanceof types.UpdateShortChatMessage) ||
613
616
  (update instanceof types.UpdateShortSentMessage)) {
614
- const localState = await this.getLocalState();
615
- if (localState.pts + update.ptsCount > update.pts) {
616
- // the update is already applied
617
- return;
618
- }
619
- else if (localState.pts + update.ptsCount < update.pts) {
620
- // there is an update gap that needs to be filled
621
- throw UPDATE_GAP;
617
+ if (update.pts != 0 && update.ptsCount != 0) {
618
+ const localState = await this.getLocalState();
619
+ if (localState.pts + update.ptsCount > update.pts) {
620
+ // the update is already applied
621
+ return;
622
+ }
623
+ else if (localState.pts + update.ptsCount < update.pts) {
624
+ // there is an update gap that needs to be filled
625
+ throw UPDATE_GAP;
626
+ }
627
+ localState.pts = update.pts;
628
+ d("applied update with pts %d", update.pts);
629
+ await this.storage.setState(localState);
622
630
  }
623
- localState.pts = update.pts;
624
- d("applied update with pts %d", update.pts);
625
- await this.storage.setState(localState);
626
631
  }
627
632
  else if (usePts &&
628
633
  ((update instanceof types.UpdateNewChannelMessage) ||
@@ -722,7 +727,8 @@ export class Client extends ClientAbstract {
722
727
  }
723
728
  }
724
729
  }
725
- async processUpdates(updates) {
730
+ async processUpdates(updates, release) {
731
+ release ??= await this.updateProcessLock.acquire();
726
732
  try {
727
733
  if (updates instanceof types.TypeUpdates) {
728
734
  if (updates instanceof types.Updates) {
@@ -730,7 +736,7 @@ export class Client extends ClientAbstract {
730
736
  await this.processUsers(updates.users);
731
737
  await this.setUpdateStateDate(updates.date);
732
738
  for (const update of updates.updates) {
733
- await this.processUpdates(update);
739
+ await this.processUpdates(update, release);
734
740
  }
735
741
  }
736
742
  else if (updates instanceof types.UpdateShortMessage ||
@@ -747,7 +753,7 @@ export class Client extends ClientAbstract {
747
753
  await this.processChats(updates.chats);
748
754
  await this.processUsers(updates.users);
749
755
  for (const update of updates.updates) {
750
- await this.processUpdates(update);
756
+ await this.processUpdates(update, release);
751
757
  }
752
758
  }
753
759
  }
@@ -776,6 +782,9 @@ export class Client extends ClientAbstract {
776
782
  catch (err) {
777
783
  d("error processing updates: %O", err);
778
784
  }
785
+ finally {
786
+ release();
787
+ }
779
788
  }
780
789
  async setUpdateStateDate(date) {
781
790
  const release = await this.updateApplicationMutex.acquire();
@@ -818,6 +827,7 @@ export class Client extends ClientAbstract {
818
827
  await this.applyUpdateNoGap(update);
819
828
  }
820
829
  if (difference instanceof types.UpdatesDifference) {
830
+ await this.storage.setState(difference.state[as](types.UpdatesState));
821
831
  dGap("recovered from update gap");
822
832
  break;
823
833
  }
@@ -1111,4 +1121,68 @@ export class Client extends ClientAbstract {
1111
1121
  const messages = await this.getMessages(chatId, [messageId]);
1112
1122
  return messages[0] ?? null;
1113
1123
  }
1124
+ async *downloadInner(location, dcId) {
1125
+ let client = null;
1126
+ if (dcId != undefined && dcId != this.dcId) {
1127
+ const exportedAuth = await this.invoke(new functions.AuthExportAuthorization({ dcId }));
1128
+ client = new Client(new StorageMemory(), this.apiId, this.apiHash, {
1129
+ transportProvider: this.transportProvider,
1130
+ appVersion: this.appVersion,
1131
+ deviceModel: this.deviceModel,
1132
+ langCode: this.langCode,
1133
+ langPack: this.langPack,
1134
+ systemLangCode: this.systemLangCode,
1135
+ systemVersion: this.systemVersion,
1136
+ }, true);
1137
+ let dc = String(dcId);
1138
+ if (this.dcId < 0) {
1139
+ dc += "-test";
1140
+ }
1141
+ await client.setDc(dc);
1142
+ await client.connect();
1143
+ await client.authorize(exportedAuth);
1144
+ }
1145
+ const limit = 1024 * 1024;
1146
+ let offset = 0n;
1147
+ while (true) {
1148
+ const file = await (client ?? this).invoke(new functions.UploadGetFile({ location, offset, limit }));
1149
+ if (file instanceof types.UploadFile) {
1150
+ yield file.bytes;
1151
+ if (file.bytes.length < limit) {
1152
+ break;
1153
+ }
1154
+ else {
1155
+ offset += BigInt(file.bytes.length);
1156
+ }
1157
+ }
1158
+ else {
1159
+ UNREACHABLE();
1160
+ }
1161
+ }
1162
+ }
1163
+ async download(fileId_) {
1164
+ const fileId = FileID.decode(fileId_);
1165
+ switch (fileId.fileType) {
1166
+ case FileType.ChatPhoto: {
1167
+ const big = fileId.params.thumbnailSource == ThumbnailSource.ChatPhotoBig;
1168
+ const peer = await this.getInputPeer(fileId.params.chatId);
1169
+ const location = new types.InputPeerPhotoFileLocation({ big: big ? true : undefined, peer, photoId: fileId.params.mediaId });
1170
+ return this.downloadInner(location);
1171
+ }
1172
+ case FileType.Photo: {
1173
+ if (fileId.params.mediaId == undefined || fileId.params.accessHash == undefined || fileId.params.fileReference == undefined || fileId.params.thumbnailSize == undefined) {
1174
+ UNREACHABLE();
1175
+ }
1176
+ const location = new types.InputPhotoFileLocation({
1177
+ id: fileId.params.mediaId,
1178
+ accessHash: fileId.params.accessHash,
1179
+ fileReference: fileId.params.fileReference,
1180
+ thumbSize: fileId.params.thumbnailSize,
1181
+ });
1182
+ return this.downloadInner(location);
1183
+ }
1184
+ default:
1185
+ UNREACHABLE();
1186
+ }
1187
+ }
1114
1188
  }
@@ -4,7 +4,7 @@ export declare const publicKeys: Map<bigint, [bigint, bigint]>;
4
4
  export declare const VECTOR_CONSTRUCTOR = 481674261;
5
5
  export declare const DEFAULT_INITIAL_DC: DC;
6
6
  export declare const LAYER = 158;
7
- export declare const DEFAULT_APP_VERSION = "MTKruto 0.0.910";
7
+ export declare const DEFAULT_APP_VERSION = "MTKruto 0.0.921";
8
8
  export declare const DEFAULT_DEVICE_MODEL: string;
9
9
  export declare const DEFAULT_LANG_CODE: string;
10
10
  export declare const DEFAULT_LANG_PACK = "";
package/esm/constants.js CHANGED
@@ -62,7 +62,7 @@ export const publicKeys = new Map([
62
62
  export const VECTOR_CONSTRUCTOR = 0x1CB5C415;
63
63
  export const DEFAULT_INITIAL_DC = "2-test";
64
64
  export const LAYER = 158;
65
- export const DEFAULT_APP_VERSION = "MTKruto 0.0.910";
65
+ export const DEFAULT_APP_VERSION = "MTKruto 0.0.921";
66
66
  // @ts-ignore: lib
67
67
  export const DEFAULT_DEVICE_MODEL = typeof dntShim.Deno === "undefined" ? typeof navigator === "undefined" ? typeof process === "undefined" ? "Unknown" : process.platform + "-" + process.arch : navigator.userAgent.split(" ")[0] : dntShim.Deno.build.os + "-" + dntShim.Deno.build.arch;
68
68
  export const DEFAULT_LANG_CODE = typeof navigator === "undefined" ? "en" : navigator.language.split("-")[0];
package/esm/deps.d.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  export * from "./deps/deno.land/std@0.190.0/testing/asserts.js";
2
2
  export { ctr256Decrypt, ctr256Encrypt, factorize, ige256Decrypt, ige256Encrypt, init as initTgCrypto } from "./deps/deno.land/x/tgcrypto@0.1.3/mod.js";
3
3
  export { gunzip, gzip } from "./deps/raw.githubusercontent.com/MTKruto/compress/master/gzip/gzip.js";
4
- export { Mutex } from "async-mutex";
4
+ export { Mutex, type MutexInterface } from "async-mutex";
5
5
  export { Parser } from "./deps/deno.land/x/html_parser@v0.1.3/src/mod.js";
6
6
  import { debug as debug_ } from "./deps/raw.githubusercontent.com/MTKruto/debug/master/mod.js";
7
7
  export declare const debug: typeof debug_;
8
- export { queue } from "./deps/deno.land/x/q@v0.0.1/mod.js";
9
8
  export { decode as base64Decode, encode as base64Encode } from "./deps/deno.land/std@0.190.0/encoding/base64.js";
package/esm/deps.js CHANGED
@@ -5,5 +5,4 @@ export { Mutex } from "async-mutex";
5
5
  export { Parser } from "./deps/deno.land/x/html_parser@v0.1.3/src/mod.js";
6
6
  import { debug as debug_ } from "./deps/raw.githubusercontent.com/MTKruto/debug/master/mod.js";
7
7
  export const debug = (v) => debug_(`mtkruto/${v}`);
8
- export { queue } from "./deps/deno.land/x/q@v0.0.1/mod.js";
9
8
  export { decode as base64Decode, encode as base64Encode } from "./deps/deno.land/std@0.190.0/encoding/base64.js";
@@ -36,19 +36,19 @@ interface FileIDParams {
36
36
  thumbnailSize?: string;
37
37
  secret?: bigint;
38
38
  localId?: number;
39
- chatId?: bigint;
39
+ chatId?: number;
40
40
  chatAccessHash?: bigint;
41
41
  stickerSetId?: bigint;
42
42
  stickerSetAccessHash?: bigint;
43
43
  }
44
44
  export declare class FileID {
45
- private readonly fileType;
46
- private readonly dcId;
47
- private readonly params;
45
+ readonly fileType: FileType;
46
+ readonly dcId: number;
47
+ readonly params: FileIDParams;
48
48
  static MAJOR: number;
49
49
  static MINOR: number;
50
- private readonly major;
51
- private readonly minor;
50
+ readonly major: number;
51
+ readonly minor: number;
52
52
  constructor(major: number | null | undefined, minor: number | null | undefined, fileType: FileType, dcId: number, params: FileIDParams);
53
53
  static decode(fileId: string): FileID;
54
54
  encode(major?: number, minor?: number): string;
@@ -1,14 +1,9 @@
1
1
  // Direct port from Pyrogram
2
- import { base64Decode as base64Decode_, base64Encode as base64Encode_ } from "../deps.js";
2
+ import { base64DecodeUrlSafe, base64EncodeUrlSafe } from "../utilities/0_base64.js";
3
3
  import { UNREACHABLE } from "../utilities/0_control.js";
4
+ import { rleDecode, rleEncode } from "../utilities/0_rle.js";
4
5
  import { TLRawWriter } from "../tl/0_tl_raw_writer.js";
5
6
  import { TLRawReader } from "../tl/0_tl_raw_reader.js";
6
- function base64Encode(data) {
7
- return base64Encode_(data).replace(/=*$/, "");
8
- }
9
- function base64Decode(data) {
10
- return base64Decode_(data + "=".repeat(-data.length % 4));
11
- }
12
7
  export var FileType;
13
8
  (function (FileType) {
14
9
  FileType[FileType["Thumbnail"] = 0] = "Thumbnail";
@@ -42,48 +37,6 @@ export var ThumbnailSource;
42
37
  })(ThumbnailSource || (ThumbnailSource = {}));
43
38
  const WEB_LOCATION_FLAG = 1 << 24;
44
39
  const FILE_REFERENCE_FLAG = 1 << 25;
45
- function rleEncode(s) {
46
- const r = new Array();
47
- let n = 0;
48
- for (const b of s) {
49
- if (!b) {
50
- n++;
51
- }
52
- else {
53
- if (n) {
54
- r.push(0);
55
- r.push(n);
56
- n = 0;
57
- }
58
- r.push(b);
59
- }
60
- }
61
- if (n) {
62
- r.push(0);
63
- r.push(n);
64
- }
65
- return new Uint8Array(r);
66
- }
67
- function rleDecode(s) {
68
- const r = new Array();
69
- let z = false;
70
- for (const b of s) {
71
- if (!b) {
72
- z = true;
73
- continue;
74
- }
75
- if (z) {
76
- for (let i = 0; i < b; i++) {
77
- r.push(0);
78
- }
79
- z = false;
80
- }
81
- else {
82
- r.push(b);
83
- }
84
- }
85
- return new Uint8Array(r);
86
- }
87
40
  class FileID {
88
41
  constructor(major = FileID.MAJOR, minor = FileID.MINOR, fileType, dcId, params) {
89
42
  Object.defineProperty(this, "fileType", {
@@ -131,7 +84,7 @@ class FileID {
131
84
  this.params.thumbnailSize ??= "";
132
85
  }
133
86
  static decode(fileId) {
134
- const decoded = rleDecode(base64Decode(fileId));
87
+ const decoded = rleDecode(base64DecodeUrlSafe(fileId));
135
88
  const major = decoded[decoded.length - 1];
136
89
  let minor;
137
90
  let buffer;
@@ -165,7 +118,7 @@ class FileID {
165
118
  const volumeId = reader.readInt64();
166
119
  let thumbnailSource = 0;
167
120
  if (major >= 4) {
168
- thumbnailSource = reader.readInt32();
121
+ thumbnailSource = reader.readInt32(false);
169
122
  }
170
123
  switch (thumbnailSource) {
171
124
  case ThumbnailSource.Legacy: {
@@ -181,10 +134,10 @@ class FileID {
181
134
  }
182
135
  case ThumbnailSource.ChatPhotoSmall:
183
136
  case ThumbnailSource.ChatPhotoBig: {
184
- const chatId = reader.readInt64();
137
+ const chatId = Number(reader.readInt64());
185
138
  const chatAccessHash = reader.readInt64();
186
139
  const localId = reader.readInt32();
187
- return new FileID(major, minor, fileType, dcId, { fileReference, mediaId, accessHash, volumeId, thumbnailSource, chatId, chatAccessHash, localId });
140
+ return new FileID(major, minor, fileType, dcId, { fileReference, mediaId, accessHash, volumeId, thumbnailSource, chatId: Number(chatId), chatAccessHash, localId });
188
141
  }
189
142
  case ThumbnailSource.StickerSetThumbnail: {
190
143
  const stickerSetId = reader.readInt64();
@@ -232,7 +185,7 @@ class FileID {
232
185
  UNREACHABLE();
233
186
  }
234
187
  writer.writeInt64(this.params.volumeId);
235
- if (major > 4) {
188
+ if (major >= 4) {
236
189
  writer.writeInt32(Number(this.params.thumbnailSource));
237
190
  }
238
191
  switch (this.params.thumbnailSource) {
@@ -256,7 +209,7 @@ class FileID {
256
209
  if (this.params.chatId == undefined || this.params.chatAccessHash == undefined) {
257
210
  UNREACHABLE();
258
211
  }
259
- writer.writeInt64(this.params.chatId);
212
+ writer.writeInt64(BigInt(this.params.chatId));
260
213
  writer.writeInt64(this.params.chatAccessHash);
261
214
  writer.writeInt32(this.params.localId);
262
215
  break;
@@ -280,7 +233,7 @@ class FileID {
280
233
  UNREACHABLE();
281
234
  }
282
235
  writer.write(new Uint8Array([minor, major]));
283
- return base64Encode(rleEncode(writer.buffer));
236
+ return base64EncodeUrlSafe(rleEncode(writer.buffer));
284
237
  }
285
238
  }
286
239
  Object.defineProperty(FileID, "MAJOR", {
@@ -321,7 +274,7 @@ export class FileUniqueID {
321
274
  });
322
275
  }
323
276
  static decode(fileId) {
324
- const reader = new TLRawReader(rleDecode(base64Decode(fileId)));
277
+ const reader = new TLRawReader(rleDecode(base64DecodeUrlSafe(fileId)));
325
278
  const fileUniqueType = reader.readInt32();
326
279
  switch (fileUniqueType) {
327
280
  case FileUniqueType.Web: {
@@ -367,6 +320,6 @@ export class FileUniqueID {
367
320
  default:
368
321
  UNREACHABLE();
369
322
  }
370
- return base64Encode(rleEncode(writer.buffer));
323
+ return base64EncodeUrlSafe(rleEncode(writer.buffer));
371
324
  }
372
325
  }
@@ -5,6 +5,7 @@ export declare namespace ChatPhoto {
5
5
  smallFileUniqueId: string;
6
6
  bigFileId: string;
7
7
  bigFileUniqueId: string;
8
+ hasVideo: boolean;
8
9
  }
9
10
  interface User extends Base {
10
11
  personal: boolean;
@@ -4,7 +4,7 @@ export function constructChatPhoto(photo, chatId, chatAccessHash) {
4
4
  const smallFileId = new FileID(null, null, FileType.ChatPhoto, photo.dcId, {
5
5
  mediaId: photo.photoId,
6
6
  thumbnailSource: ThumbnailSource.ChatPhotoSmall,
7
- chatId: BigInt(chatId),
7
+ chatId,
8
8
  chatAccessHash,
9
9
  accessHash: 0n,
10
10
  volumeId: 0n,
@@ -14,7 +14,7 @@ export function constructChatPhoto(photo, chatId, chatAccessHash) {
14
14
  const bigFileId = new FileID(null, null, FileType.ChatPhoto, photo.dcId, {
15
15
  mediaId: photo.photoId,
16
16
  thumbnailSource: ThumbnailSource.ChatPhotoBig,
17
- chatId: BigInt(chatId),
17
+ chatId,
18
18
  chatAccessHash,
19
19
  accessHash: 0n,
20
20
  volumeId: 0n,
@@ -27,6 +27,7 @@ export function constructChatPhoto(photo, chatId, chatAccessHash) {
27
27
  smallFileUniqueId,
28
28
  bigFileId,
29
29
  bigFileUniqueId,
30
+ hasVideo: photo.hasVideo || false,
30
31
  };
31
32
  }
32
33
  else {
@@ -36,6 +37,7 @@ export function constructChatPhoto(photo, chatId, chatAccessHash) {
36
37
  smallFileUniqueId,
37
38
  bigFileId,
38
39
  bigFileUniqueId,
40
+ hasVideo: photo.hasVideo || false,
39
41
  };
40
42
  }
41
43
  }
@@ -0,0 +1,9 @@
1
+ import * as types from "../tl/2_types.js";
2
+ export interface Thumbnail {
3
+ fileId: string;
4
+ fileUniqueId: string;
5
+ width: number;
6
+ height: number;
7
+ fileSize: number;
8
+ }
9
+ export declare function constructThumbnail(size: types.PhotoSize, fileId: string, fileUniqueId: string): Thumbnail;
@@ -0,0 +1,9 @@
1
+ export function constructThumbnail(size, fileId, fileUniqueId) {
2
+ return {
3
+ fileId,
4
+ fileUniqueId,
5
+ width: size.w,
6
+ height: size.h,
7
+ fileSize: size.size,
8
+ };
9
+ }