@mtcute/test 0.1.1 → 0.2.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.
Files changed (65) hide show
  1. package/cjs/client.d.ts +14 -3
  2. package/cjs/client.js +39 -21
  3. package/cjs/client.js.map +1 -1
  4. package/cjs/client.test.d.ts +1 -0
  5. package/cjs/client.test.js +32 -0
  6. package/cjs/client.test.js.map +1 -0
  7. package/cjs/crypto.d.ts +6 -0
  8. package/cjs/crypto.js +176 -0
  9. package/cjs/crypto.js.map +1 -0
  10. package/cjs/index.d.ts +2 -0
  11. package/cjs/index.js +2 -0
  12. package/cjs/index.js.map +1 -1
  13. package/cjs/schema.js +25 -2
  14. package/cjs/schema.js.map +1 -1
  15. package/cjs/storage-test.d.ts +24 -0
  16. package/cjs/storage-test.js +345 -0
  17. package/cjs/storage-test.js.map +1 -0
  18. package/cjs/storage.d.ts +2 -1
  19. package/cjs/storage.js +2 -1
  20. package/cjs/storage.js.map +1 -1
  21. package/cjs/storage.test.d.ts +1 -0
  22. package/cjs/storage.test.js +43 -0
  23. package/cjs/storage.test.js.map +1 -0
  24. package/cjs/stub.test.d.ts +1 -0
  25. package/cjs/stub.test.js +55 -0
  26. package/cjs/stub.test.js.map +1 -0
  27. package/cjs/transport.test.d.ts +1 -0
  28. package/cjs/transport.test.js +37 -0
  29. package/cjs/transport.test.js.map +1 -0
  30. package/cjs/utils.test.d.ts +1 -0
  31. package/cjs/utils.test.js +16 -0
  32. package/cjs/utils.test.js.map +1 -0
  33. package/esm/client.d.ts +14 -3
  34. package/esm/client.js +40 -22
  35. package/esm/client.js.map +1 -1
  36. package/esm/client.test.d.ts +1 -0
  37. package/esm/client.test.js +30 -0
  38. package/esm/client.test.js.map +1 -0
  39. package/esm/crypto.d.ts +6 -0
  40. package/esm/crypto.js +168 -0
  41. package/esm/crypto.js.map +1 -0
  42. package/esm/index.d.ts +2 -0
  43. package/esm/index.js +2 -0
  44. package/esm/index.js.map +1 -1
  45. package/esm/schema.js +2 -2
  46. package/esm/schema.js.map +1 -1
  47. package/esm/storage-test.d.ts +24 -0
  48. package/esm/storage-test.js +337 -0
  49. package/esm/storage-test.js.map +1 -0
  50. package/esm/storage.d.ts +2 -1
  51. package/esm/storage.js +2 -1
  52. package/esm/storage.js.map +1 -1
  53. package/esm/storage.test.d.ts +1 -0
  54. package/esm/storage.test.js +41 -0
  55. package/esm/storage.test.js.map +1 -0
  56. package/esm/stub.test.d.ts +1 -0
  57. package/esm/stub.test.js +50 -0
  58. package/esm/stub.test.js.map +1 -0
  59. package/esm/transport.test.d.ts +1 -0
  60. package/esm/transport.test.js +35 -0
  61. package/esm/transport.test.js.map +1 -0
  62. package/esm/utils.test.d.ts +1 -0
  63. package/esm/utils.test.js +14 -0
  64. package/esm/utils.test.js.map +1 -0
  65. package/package.json +4 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.test.js","sourceRoot":"","sources":["../../src/transport.test.ts"],"names":[],"mappings":";;AAAA,mCAA6C;AAE7C,uCAAiD;AACjD,kEAAkE;AAElE,uCAAsC;AACtC,iDAAsD;AAEtD,IAAA,iBAAQ,EAAC,gBAAgB,EAAE,GAAG,EAAE;IAC5B,IAAA,WAAE,EAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,GAAG,GAAa,EAAE,CAAA;QAExB,MAAM,MAAM,GAAG,IAAI,yBAAkB,CAAC;YAClC,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,CAAC;YACX,UAAU,EAAE;gBACR,IAAI,EAAE,IAAA,oBAAU,EAAC,UAAU,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBAClE,KAAK,EAAE,IAAA,oBAAU,EAAC,UAAU,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;aACtE;YACD,OAAO,EAAE,IAAI,yBAAa,EAAE;YAC5B,SAAS,EAAE,GAAG,EAAE,CACZ,IAAI,oCAAqB,CAAC;gBACtB,SAAS,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE;oBACxB,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,IAAI,SAAS,QAAQ,EAAE,CAAC,CAAA;oBAC/D,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;gBAClC,CAAC;gBACD,SAAS,CAAC,GAAG;oBACT,GAAG,CAAC,IAAI,CAAC,gBAAgB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;gBAC1C,CAAC;aACJ,CAAC;SACT,CAAC,CAAA;QAEF,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA,CAAC,+BAA+B;QAEtE,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,OAAO,CAAC;YAChB,iBAAiB;YACjB,iCAAiC;SACpC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA","sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport { BaseTelegramClient } from '@mtcute/core'\nimport { MemoryStorage } from '@mtcute/core/src/storage/memory.js'\n\nimport { createStub } from './stub.js'\nimport { StubTelegramTransport } from './transport.js'\n\ndescribe('transport stub', () => {\n it('should correctly intercept calls', async () => {\n const log: string[] = []\n\n const client = new BaseTelegramClient({\n apiId: 0,\n apiHash: '',\n logLevel: 0,\n defaultDcs: {\n main: createStub('dcOption', { ipAddress: '1.2.3.4', port: 1234 }),\n media: createStub('dcOption', { ipAddress: '1.2.3.4', port: 5678 }),\n },\n storage: new MemoryStorage(),\n transport: () =>\n new StubTelegramTransport({\n onConnect: (dc, testMode) => {\n log.push(`connect ${dc.ipAddress}:${dc.port} test=${testMode}`)\n client.close().catch(() => {})\n },\n onMessage(msg) {\n log.push(`message size=${msg.length}`)\n },\n }),\n })\n\n await client.connect().catch(() => {}) // ignore \"client closed\" error\n\n expect(log).toEqual([\n 'message size=40', // req_pq_multi\n 'connect 1.2.3.4:1234 test=false',\n ])\n })\n})\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const utils_js_1 = require("./utils.js");
5
+ (0, vitest_1.describe)('markedIdToPeer', () => {
6
+ (0, vitest_1.it)('should correctly convert user ids', () => {
7
+ (0, vitest_1.expect)((0, utils_js_1.markedIdToPeer)(12345)).toEqual({ _: 'peerUser', userId: 12345 });
8
+ });
9
+ (0, vitest_1.it)('should correctly convert chat ids', () => {
10
+ (0, vitest_1.expect)((0, utils_js_1.markedIdToPeer)(-12345)).toEqual({ _: 'peerChat', chatId: 12345 });
11
+ });
12
+ (0, vitest_1.it)('should correctly convert channel ids', () => {
13
+ (0, vitest_1.expect)((0, utils_js_1.markedIdToPeer)(-1000000012345)).toEqual({ _: 'peerChannel', channelId: 12345 });
14
+ });
15
+ });
16
+ //# sourceMappingURL=utils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../src/utils.test.ts"],"names":[],"mappings":";;AAAA,mCAA6C;AAE7C,yCAA2C;AAE3C,IAAA,iBAAQ,EAAC,gBAAgB,EAAE,GAAG,EAAE;IAC5B,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;QACzC,IAAA,eAAM,EAAC,IAAA,yBAAc,EAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;IAC3E,CAAC,CAAC,CAAA;IAEF,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;QACzC,IAAA,eAAM,EAAC,IAAA,yBAAc,EAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;IAC5E,CAAC,CAAC,CAAA;IAEF,IAAA,WAAE,EAAC,sCAAsC,EAAE,GAAG,EAAE;QAC5C,IAAA,eAAM,EAAC,IAAA,yBAAc,EAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAA;IAC1F,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA","sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport { markedIdToPeer } from './utils.js'\n\ndescribe('markedIdToPeer', () => {\n it('should correctly convert user ids', () => {\n expect(markedIdToPeer(12345)).toEqual({ _: 'peerUser', userId: 12345 })\n })\n\n it('should correctly convert chat ids', () => {\n expect(markedIdToPeer(-12345)).toEqual({ _: 'peerChat', chatId: 12345 })\n })\n\n it('should correctly convert channel ids', () => {\n expect(markedIdToPeer(-1000000012345)).toEqual({ _: 'peerChannel', channelId: 12345 })\n })\n})\n"]}
package/esm/client.d.ts CHANGED
@@ -7,11 +7,22 @@ interface MessageBox {
7
7
  type InputPeerId = number | tl.TypePeer | false | undefined;
8
8
  export declare class StubTelegramClient extends BaseTelegramClient {
9
9
  constructor(params?: Partial<BaseTelegramClientOptions>);
10
+ /**
11
+ * Create a fake client that may not actually be used for API calls
12
+ *
13
+ * Useful for testing "offline" methods
14
+ */
15
+ static offline(): StubTelegramClient;
16
+ /**
17
+ * Create a fake "full" client (i.e. TelegramClient)
18
+ *
19
+ * Basically a proxy that returns an empty function for every unknown method
20
+ */
21
+ static full(): any;
10
22
  readonly _knownChats: Map<number, tl.TypeChat>;
11
23
  readonly _knownUsers: Map<number, tl.TypeUser>;
12
24
  _selfId: number;
13
- registerChat(chat: tl.TypeChat | tl.TypeChat[]): void;
14
- registerUser(user: tl.TypeUser | tl.TypeUser[]): void;
25
+ registerPeers(...peers: (tl.TypeUser | tl.TypeChat)[]): Promise<void>;
15
26
  getPeers(ids: InputPeerId[]): {
16
27
  users: tl.TypeUser[];
17
28
  chats: tl.TypeChat[];
@@ -20,7 +31,7 @@ export declare class StubTelegramClient extends BaseTelegramClient {
20
31
  onRawMessage(fn: (data: Uint8Array) => void): void;
21
32
  private _responders;
22
33
  addResponder<T extends tl.RpcMethod['_']>(responders: InputResponder<T>): void;
23
- respondWith<T extends tl.RpcMethod['_']>(method: T, response: tl.RpcCallReturn[T] | ((data: tl.FindByName<tl.RpcMethod, T>) => tl.RpcCallReturn[T])): void;
34
+ respondWith<T extends tl.RpcMethod['_'], Fn extends (data: tl.FindByName<tl.RpcMethod, T>) => MaybeAsync<tl.RpcCallReturn[T]>>(method: T, response: Fn): Fn;
24
35
  call<T extends tl.RpcMethod>(message: MustEqual<T, tl.RpcMethod>, params?: RpcCallOptions): Promise<tl.RpcCallReturn[T['_']]>;
25
36
  private _fakeMessageBoxes;
26
37
  private _lastQts;
package/esm/client.js CHANGED
@@ -1,4 +1,4 @@
1
- import { BaseTelegramClient } from '@mtcute/core';
1
+ import { BaseTelegramClient, tl } from '@mtcute/core';
2
2
  import { StubMemoryTelegramStorage } from './storage.js';
3
3
  import { StubTelegramTransport } from './transport.js';
4
4
  import { markedIdToPeer } from './utils.js';
@@ -45,25 +45,46 @@ export class StubTelegramClient extends BaseTelegramClient {
45
45
  this._lastDate = Math.floor(Date.now() / 1000);
46
46
  this._lastSeq = 0;
47
47
  }
48
- registerChat(chat) {
49
- if (Array.isArray(chat)) {
50
- for (const c of chat) {
51
- this.registerChat(c);
52
- }
53
- return;
54
- }
55
- this._knownChats.set(chat.id, chat);
48
+ /**
49
+ * Create a fake client that may not actually be used for API calls
50
+ *
51
+ * Useful for testing "offline" methods
52
+ */
53
+ static offline() {
54
+ const client = new StubTelegramClient();
55
+ client.call = (obj) => {
56
+ throw new Error(`Expected offline client to not make any API calls (method called: ${obj._})`);
57
+ };
58
+ return client;
59
+ }
60
+ /**
61
+ * Create a fake "full" client (i.e. TelegramClient)
62
+ *
63
+ * Basically a proxy that returns an empty function for every unknown method
64
+ */
65
+ static full() {
66
+ const client = new StubTelegramClient();
67
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
68
+ return new Proxy(client, {
69
+ get(target, prop) {
70
+ if (typeof prop === 'string' && !(prop in target)) {
71
+ return () => { };
72
+ }
73
+ return target[prop];
74
+ },
75
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
+ });
77
+ // i don't want to type this properly since it would require depending test utils on client
56
78
  }
57
- registerUser(user) {
58
- if (Array.isArray(user)) {
59
- for (const u of user) {
60
- this.registerUser(u);
79
+ async registerPeers(...peers) {
80
+ for (const peer of peers) {
81
+ if (tl.isAnyUser(peer)) {
82
+ this._knownUsers.set(peer.id, peer);
61
83
  }
62
- return;
63
- }
64
- this._knownUsers.set(user.id, user);
65
- if (user._ === 'user' && user.self) {
66
- this._selfId = user.id;
84
+ else {
85
+ this._knownChats.set(peer.id, peer);
86
+ }
87
+ await this._cachePeersFrom(peer);
67
88
  }
68
89
  }
69
90
  getPeers(ids) {
@@ -118,12 +139,9 @@ export class StubTelegramClient extends BaseTelegramClient {
118
139
  this.respondWith(method, responder);
119
140
  }
120
141
  respondWith(method, response) {
121
- if (typeof response !== 'function') {
122
- const res = response;
123
- response = () => res;
124
- }
125
142
  // eslint-disable-next-line
126
143
  this._responders.set(method, response);
144
+ return response;
127
145
  }
128
146
  async call(message, params) {
129
147
  if (this._responders.has(message._)) {
package/esm/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseTelegramClient, BaseTelegramClientOptions, MaybeAsync, MustEqual, RpcCallOptions, tl } from '@mtcute/core'\n\nimport { StubMemoryTelegramStorage } from './storage.js'\nimport { StubTelegramTransport } from './transport.js'\nimport { InputResponder } from './types.js'\nimport { markedIdToPeer } from './utils.js'\n\ninterface MessageBox {\n pts: number\n lastMessageId: number\n}\n\ntype InputPeerId = number | tl.TypePeer | false | undefined\n\nexport class StubTelegramClient extends BaseTelegramClient {\n constructor(params?: Partial<BaseTelegramClientOptions>) {\n const storage = new StubMemoryTelegramStorage({\n hasKeys: true,\n hasTempKeys: true,\n })\n\n super({\n apiId: 0,\n apiHash: '',\n logLevel: 0,\n storage,\n transport: () => {\n const transport = new StubTelegramTransport({\n onMessage: (data) => {\n if (!this._onRawMessage) {\n if (this._responders.size) {\n this._emitError(new Error('Unexpected outgoing message'))\n }\n\n return\n }\n\n const dcId = transport._currentDc!.id\n const key = storage.getAuthKeyFor(dcId)\n\n if (key) {\n this._onRawMessage(storage.decryptOutgoingMessage(transport._crypto, data, dcId))\n }\n },\n })\n\n return transport\n },\n ...params,\n })\n }\n\n // some fake peers handling //\n\n readonly _knownChats = new Map<number, tl.TypeChat>()\n readonly _knownUsers = new Map<number, tl.TypeUser>()\n _selfId = 0\n\n registerChat(chat: tl.TypeChat | tl.TypeChat[]): void {\n if (Array.isArray(chat)) {\n for (const c of chat) {\n this.registerChat(c)\n }\n\n return\n }\n\n this._knownChats.set(chat.id, chat)\n }\n\n registerUser(user: tl.TypeUser | tl.TypeUser[]): void {\n if (Array.isArray(user)) {\n for (const u of user) {\n this.registerUser(u)\n }\n\n return\n }\n\n this._knownUsers.set(user.id, user)\n\n if (user._ === 'user' && user.self) {\n this._selfId = user.id\n }\n }\n\n getPeers(ids: InputPeerId[]) {\n const users: tl.TypeUser[] = []\n const chats: tl.TypeChat[] = []\n\n for (let id of ids) {\n if (!id) continue\n\n if (typeof id === 'number') {\n id = markedIdToPeer(id)\n }\n\n switch (id._) {\n case 'peerUser': {\n const user = this._knownUsers.get(id.userId)\n if (!user) throw new Error(`Unknown user with ID ${id.userId}`)\n\n users.push(user)\n break\n }\n case 'peerChat': {\n const chat = this._knownChats.get(id.chatId)\n if (!chat) throw new Error(`Unknown chat with ID ${id.chatId}`)\n\n chats.push(chat)\n break\n }\n case 'peerChannel': {\n const chat = this._knownChats.get(id.channelId)\n if (!chat) throw new Error(`Unknown channel with ID ${id.channelId}`)\n\n chats.push(chat)\n break\n }\n }\n }\n\n return { users, chats }\n }\n\n // method calls intercepting //\n\n private _onRawMessage?: (data: Uint8Array) => void\n onRawMessage(fn: (data: Uint8Array) => void): void {\n this._onRawMessage = fn\n }\n\n // eslint-disable-next-line func-call-spacing\n private _responders = new Map<string, (data: unknown) => unknown>()\n\n addResponder<T extends tl.RpcMethod['_']>(responders: InputResponder<T>): void {\n if (Array.isArray(responders)) {\n for (const responder of responders) {\n this.addResponder(responder as InputResponder<tl.RpcMethod['_']>)\n }\n\n return\n }\n\n if (typeof responders === 'function') {\n responders = responders(this)\n }\n\n const [method, responder] = responders\n this.respondWith(method, responder)\n }\n\n respondWith<T extends tl.RpcMethod['_']>(\n method: T,\n response: tl.RpcCallReturn[T] | ((data: tl.FindByName<tl.RpcMethod, T>) => tl.RpcCallReturn[T]),\n ) {\n if (typeof response !== 'function') {\n const res = response\n response = () => res\n }\n\n // eslint-disable-next-line\n this._responders.set(method, response as any)\n }\n\n async call<T extends tl.RpcMethod>(\n message: MustEqual<T, tl.RpcMethod>,\n params?: RpcCallOptions,\n ): Promise<tl.RpcCallReturn[T['_']]> {\n if (this._responders.has(message._)) {\n // eslint-disable-next-line\n return Promise.resolve(this._responders.get(message._)!(message)) as any\n }\n\n return super.call(message, params)\n }\n\n // some fake updates mechanism //\n\n private _fakeMessageBoxes = new Map<number, MessageBox>()\n private _lastQts = 0\n private _lastDate = Math.floor(Date.now() / 1000)\n private _lastSeq = 0\n\n getMessageBox(chatId = 0): MessageBox {\n const state = this._fakeMessageBoxes.get(chatId)\n\n if (!state) {\n const newState = { pts: 0, lastMessageId: 0 }\n this._fakeMessageBoxes.set(chatId, newState)\n\n return newState\n }\n\n return state\n }\n\n getNextMessageId(chatId = 0) {\n const state = this.getMessageBox(chatId)\n\n const nextId = state.lastMessageId + 1\n state.lastMessageId = nextId\n\n return nextId\n }\n\n getNextPts(chatId = 0, count = 1) {\n const state = this.getMessageBox(chatId)\n\n const nextPts = state.pts + count\n state.pts = nextPts\n\n return nextPts\n }\n\n getNextQts() {\n return this._lastQts++\n }\n\n getNextDate() {\n return (this._lastDate = Math.floor(Date.now() / 1000))\n }\n\n createStubUpdates(params: {\n updates: tl.TypeUpdate[]\n peers?: (number | tl.TypePeer)[]\n seq?: number\n seqCount?: number\n }): tl.TypeUpdates {\n const { peers, updates, seq = 0, seqCount = 1 } = params\n\n const { users, chats } = this.getPeers(peers ?? [])\n\n const seqStart = seq - seqCount + 1\n\n if (seq !== 0) {\n this._lastSeq = seq + seqCount\n }\n\n if (seqStart !== seq) {\n return {\n _: 'updatesCombined',\n updates,\n users,\n chats,\n date: this.getNextDate(),\n seq,\n seqStart,\n }\n }\n\n return {\n _: 'updates',\n updates,\n users,\n chats,\n date: this.getNextDate(),\n seq,\n }\n }\n\n // helpers //\n\n async connectAndWait() {\n await this.connect()\n await new Promise((resolve) => this.once('usable', resolve))\n }\n\n async with(fn: () => MaybeAsync<void>): Promise<void> {\n await this.connectAndWait()\n\n let error: unknown\n\n this.onError((err) => {\n error = err\n })\n\n try {\n await fn()\n } catch (e) {\n error = e\n }\n\n await this.close()\n\n if (error) {\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw error\n }\n }\n}\n"]}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseTelegramClient, BaseTelegramClientOptions, MaybeAsync, MustEqual, RpcCallOptions, tl } from '@mtcute/core'\n\nimport { StubMemoryTelegramStorage } from './storage.js'\nimport { StubTelegramTransport } from './transport.js'\nimport { InputResponder } from './types.js'\nimport { markedIdToPeer } from './utils.js'\n\ninterface MessageBox {\n pts: number\n lastMessageId: number\n}\n\ntype InputPeerId = number | tl.TypePeer | false | undefined\n\nexport class StubTelegramClient extends BaseTelegramClient {\n constructor(params?: Partial<BaseTelegramClientOptions>) {\n const storage = new StubMemoryTelegramStorage({\n hasKeys: true,\n hasTempKeys: true,\n })\n\n super({\n apiId: 0,\n apiHash: '',\n logLevel: 0,\n storage,\n transport: () => {\n const transport = new StubTelegramTransport({\n onMessage: (data) => {\n if (!this._onRawMessage) {\n if (this._responders.size) {\n this._emitError(new Error('Unexpected outgoing message'))\n }\n\n return\n }\n\n const dcId = transport._currentDc!.id\n const key = storage.getAuthKeyFor(dcId)\n\n if (key) {\n this._onRawMessage(storage.decryptOutgoingMessage(transport._crypto, data, dcId))\n }\n },\n })\n\n return transport\n },\n ...params,\n })\n }\n\n /**\n * Create a fake client that may not actually be used for API calls\n *\n * Useful for testing \"offline\" methods\n */\n static offline() {\n const client = new StubTelegramClient()\n\n client.call = (obj) => {\n throw new Error(`Expected offline client to not make any API calls (method called: ${obj._})`)\n }\n\n return client\n }\n\n /**\n * Create a fake \"full\" client (i.e. TelegramClient)\n *\n * Basically a proxy that returns an empty function for every unknown method\n */\n static full() {\n const client = new StubTelegramClient()\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return new Proxy(client, {\n get(target, prop) {\n if (typeof prop === 'string' && !(prop in target)) {\n return () => {}\n }\n\n return target[prop as keyof typeof target]\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n }) as any\n // i don't want to type this properly since it would require depending test utils on client\n }\n\n // some fake peers handling //\n\n readonly _knownChats = new Map<number, tl.TypeChat>()\n readonly _knownUsers = new Map<number, tl.TypeUser>()\n _selfId = 0\n\n async registerPeers(...peers: (tl.TypeUser | tl.TypeChat)[]): Promise<void> {\n for (const peer of peers) {\n if (tl.isAnyUser(peer)) {\n this._knownUsers.set(peer.id, peer)\n } else {\n this._knownChats.set(peer.id, peer)\n }\n\n await this._cachePeersFrom(peer)\n }\n }\n\n getPeers(ids: InputPeerId[]) {\n const users: tl.TypeUser[] = []\n const chats: tl.TypeChat[] = []\n\n for (let id of ids) {\n if (!id) continue\n\n if (typeof id === 'number') {\n id = markedIdToPeer(id)\n }\n\n switch (id._) {\n case 'peerUser': {\n const user = this._knownUsers.get(id.userId)\n if (!user) throw new Error(`Unknown user with ID ${id.userId}`)\n\n users.push(user)\n break\n }\n case 'peerChat': {\n const chat = this._knownChats.get(id.chatId)\n if (!chat) throw new Error(`Unknown chat with ID ${id.chatId}`)\n\n chats.push(chat)\n break\n }\n case 'peerChannel': {\n const chat = this._knownChats.get(id.channelId)\n if (!chat) throw new Error(`Unknown channel with ID ${id.channelId}`)\n\n chats.push(chat)\n break\n }\n }\n }\n\n return { users, chats }\n }\n\n // method calls intercepting //\n\n private _onRawMessage?: (data: Uint8Array) => void\n onRawMessage(fn: (data: Uint8Array) => void): void {\n this._onRawMessage = fn\n }\n\n // eslint-disable-next-line func-call-spacing\n private _responders = new Map<string, (data: unknown) => unknown>()\n\n addResponder<T extends tl.RpcMethod['_']>(responders: InputResponder<T>): void {\n if (Array.isArray(responders)) {\n for (const responder of responders) {\n this.addResponder(responder as InputResponder<tl.RpcMethod['_']>)\n }\n\n return\n }\n\n if (typeof responders === 'function') {\n responders = responders(this)\n }\n\n const [method, responder] = responders\n this.respondWith(method, responder)\n }\n\n respondWith<\n T extends tl.RpcMethod['_'],\n Fn extends(data: tl.FindByName<tl.RpcMethod, T>) => MaybeAsync<tl.RpcCallReturn[T]>,\n >(method: T, response: Fn): Fn {\n // eslint-disable-next-line\n this._responders.set(method, response as any)\n\n return response\n }\n\n async call<T extends tl.RpcMethod>(\n message: MustEqual<T, tl.RpcMethod>,\n params?: RpcCallOptions,\n ): Promise<tl.RpcCallReturn[T['_']]> {\n if (this._responders.has(message._)) {\n // eslint-disable-next-line\n return Promise.resolve(this._responders.get(message._)!(message)) as any\n }\n\n return super.call(message, params)\n }\n\n // some fake updates mechanism //\n\n private _fakeMessageBoxes = new Map<number, MessageBox>()\n private _lastQts = 0\n private _lastDate = Math.floor(Date.now() / 1000)\n private _lastSeq = 0\n\n getMessageBox(chatId = 0): MessageBox {\n const state = this._fakeMessageBoxes.get(chatId)\n\n if (!state) {\n const newState = { pts: 0, lastMessageId: 0 }\n this._fakeMessageBoxes.set(chatId, newState)\n\n return newState\n }\n\n return state\n }\n\n getNextMessageId(chatId = 0) {\n const state = this.getMessageBox(chatId)\n\n const nextId = state.lastMessageId + 1\n state.lastMessageId = nextId\n\n return nextId\n }\n\n getNextPts(chatId = 0, count = 1) {\n const state = this.getMessageBox(chatId)\n\n const nextPts = state.pts + count\n state.pts = nextPts\n\n return nextPts\n }\n\n getNextQts() {\n return this._lastQts++\n }\n\n getNextDate() {\n return (this._lastDate = Math.floor(Date.now() / 1000))\n }\n\n createStubUpdates(params: {\n updates: tl.TypeUpdate[]\n peers?: (number | tl.TypePeer)[]\n seq?: number\n seqCount?: number\n }): tl.TypeUpdates {\n const { peers, updates, seq = 0, seqCount = 1 } = params\n\n const { users, chats } = this.getPeers(peers ?? [])\n\n const seqStart = seq - seqCount + 1\n\n if (seq !== 0) {\n this._lastSeq = seq + seqCount\n }\n\n if (seqStart !== seq) {\n return {\n _: 'updatesCombined',\n updates,\n users,\n chats,\n date: this.getNextDate(),\n seq,\n seqStart,\n }\n }\n\n return {\n _: 'updates',\n updates,\n users,\n chats,\n date: this.getNextDate(),\n seq,\n }\n }\n\n // helpers //\n\n async connectAndWait() {\n await this.connect()\n await new Promise((resolve) => this.once('usable', resolve))\n }\n\n async with(fn: () => MaybeAsync<void>): Promise<void> {\n await this.connectAndWait()\n\n let error: unknown\n\n this.onError((err) => {\n error = err\n })\n\n try {\n await fn()\n } catch (e) {\n error = e\n }\n\n await this.close()\n\n if (error) {\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw error\n }\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,30 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { hexEncode } from '@mtcute/core/utils.js';
3
+ import { StubTelegramClient } from './client.js';
4
+ import { createStub } from './stub.js';
5
+ describe('client stub', () => {
6
+ it('should correctly intercept rpc calls', async () => {
7
+ const client = new StubTelegramClient();
8
+ const stubConfig = createStub('config');
9
+ client.respondWith('help.getConfig', () => stubConfig);
10
+ await client.with(async () => {
11
+ const result = await client.call({ _: 'help.getConfig' });
12
+ expect(result).toEqual(stubConfig);
13
+ });
14
+ });
15
+ it('should correctly decrypt intercepted raw messages', async () => {
16
+ const log = [];
17
+ const client = new StubTelegramClient();
18
+ client.onRawMessage((msg) => {
19
+ log.push(`message ctor=${hexEncode(msg.subarray(0, 4))}`);
20
+ client.close().catch(() => { });
21
+ });
22
+ await client.with(async () => {
23
+ await client.call({ _: 'help.getConfig' }).catch(() => { }); // ignore "client closed" error
24
+ expect(log).toEqual([
25
+ 'message ctor=dcf8f173', // msg_container
26
+ ]);
27
+ });
28
+ });
29
+ });
30
+ //# sourceMappingURL=client.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../src/client.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAEjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEtC,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAA;QAEvC,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAA;QACvC,MAAM,CAAC,WAAW,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,CAAA;QAEtD,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACzB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAA;YACzD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QACtC,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,GAAG,GAAa,EAAE,CAAA;QAExB,MAAM,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAA;QAEvC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,EAAE;YACxB,GAAG,CAAC,IAAI,CAAC,gBAAgB,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;YACzD,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACzB,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA,CAAC,+BAA+B;YAE1F,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;gBAChB,uBAAuB,EAAE,gBAAgB;aAC5C,CAAC,CAAA;QACN,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA","sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport { hexEncode } from '@mtcute/core/utils.js'\n\nimport { StubTelegramClient } from './client.js'\nimport { createStub } from './stub.js'\n\ndescribe('client stub', () => {\n it('should correctly intercept rpc calls', async () => {\n const client = new StubTelegramClient()\n\n const stubConfig = createStub('config')\n client.respondWith('help.getConfig', () => stubConfig)\n\n await client.with(async () => {\n const result = await client.call({ _: 'help.getConfig' })\n expect(result).toEqual(stubConfig)\n })\n })\n\n it('should correctly decrypt intercepted raw messages', async () => {\n const log: string[] = []\n\n const client = new StubTelegramClient()\n\n client.onRawMessage((msg) => {\n log.push(`message ctor=${hexEncode(msg.subarray(0, 4))}`)\n client.close().catch(() => {})\n })\n\n await client.with(async () => {\n await client.call({ _: 'help.getConfig' }).catch(() => {}) // ignore \"client closed\" error\n\n expect(log).toEqual([\n 'message ctor=dcf8f173', // msg_container\n ])\n })\n })\n})\n"]}
@@ -0,0 +1,6 @@
1
+ import { ICryptoProvider } from '@mtcute/core/utils.js';
2
+ export declare function withFakeRandom(provider: ICryptoProvider, source?: string): ICryptoProvider;
3
+ export declare function useFakeMathRandom(source?: string): void;
4
+ export declare function defaultTestCryptoProvider(source?: string): Promise<ICryptoProvider>;
5
+ export declare function testCryptoProvider(c: ICryptoProvider): void;
6
+ export declare function u8HexDecode(hex: string): Uint8Array;
package/esm/crypto.js ADDED
@@ -0,0 +1,168 @@
1
+ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { gzipSync, inflateSync } from 'zlib';
3
+ import { dataViewFromBuffer, defaultCryptoProviderFactory, hexDecodeToBuffer, hexEncode, utf8EncodeToBuffer, } from '@mtcute/core/utils.js';
4
+ // some random 1024 bytes of entropy
5
+ const DEFAULT_ENTROPY = `
6
+ 29afd26df40fb8ed10b6b4ad6d56ef5df9453f88e6ee6adb6e0544ba635dc6a8a990c9b8b980c343936b33fa7f97bae025102532233abb269c489920ef99021b
7
+ 259ce3a2c964c5c8972b4a84ff96f3375a94b535a9468f2896e2080ac7a32ed58e910474a4b02415e07671cbb5bdd58a5dd26fd137c4c98b8c346571fae6ead3
8
+ 9dfd612bd6b480b6723433f5218e9d6e271591153fb3ffefc089f7e848d3f4633459fff66b33cf939e5655813149fa34be8625f9bc4814d1ee6cf40e4d0de229
9
+ 1aa22e68c8ad8cc698103734f9aaf79f2bdc052a787a7a9b3629d1ed38750f88cb0481c0ba30a9c611672f9a4d1dc02637abb4e98913ee810a3b152d3d75f25d
10
+ 7efdc263c08833569968b1771ebbe843d187e2c917d9ad8e8865e44b69f7b74d72ab86a4ef1891dce196ee11a7c9d7d8074fc0450e745bd3a827d77bb0820b90
11
+ 3055dc15f0abd897ea740a99606b64d28968d770b5e43492ddbf07a7c75104d3e522be9b72050c0fdae8412cdf49014be21105b87a06cb7202dd580387adc007
12
+ 6280d98b015a1a413819d817f007939d1490467a1ef85a345584c7e594bb729c12a1233f806e515e7088360219dfa109264310ba84777b93eb1ad3c40727a25a
13
+ a5d9cdd6748c6ab2ca0bd4daa2ba8225bce2b066a163bcacf05609fc84055bb86a4742c28addd7d7ab8d87b64cfde0b3f4b3bc8e05f3d0a1a2fadb294860e099
14
+ a10b3721b0d5b28918b8fb49a18a82a0fde6680a64ed915637805e35ffe8b2c1d4177ec10d10eaaf24425e0351b6a89e794944e1aa82eb5c0210a37da66cccac
15
+ 895398cf915a8aa141f611521fc258514a99c02721113942c66f2c9a8f9601ff0044a953d17a47b07ad1b5f8725cc020a1a5239be65db0a43d42c206903740f0
16
+ 27c3f749ecfff2e646570118cd54db2fec392b44d8eb8377309f3e4d164dbc0530914b117b9d278b06db8359d97442d4dcbcaff93cd9a08a6b06a5ba8725d0d7
17
+ 06b313a5d792be254d33e087b7a4fafcdf819941b9bec4c6057d4c050bd01eb243efd4e6b707281b127820a2b734c6d8f6b2131bf0b5b215c7a798ff3fe90ceb
18
+ da91539fcc7b03d2b8b1381bd6023fff20278344ad944d364ba684842db3901c346335f0d455eda414f99c1e794a86aa3a90bcc6e085eecb0b4bf61198d16ed3
19
+ 89cfa495f977a37a51502b2f60649f2efd7d89c757b6366776ba4c0612017bf1fbfc682dd62e9960d39cbea854d2dcc708b1db5d268192954d13ee72c0bb1bd8
20
+ 558a3cf3b02b1cd795b40f7a57780391bb8724883d3f7764846c3823e165b3f8c025f59d896905f9a955478586ce57f820d958a01aa59a4cace7ecdf125df334
21
+ fa3de8e50aac96c1275591a1221c32a60a1513370a33a228e00894341b10cf44a6ae6ac250d17a364e956ab1a17b068df3fb2d5b5a672d8a409eeb8b6ca1ade6
22
+ `.replace(/\s/g, '');
23
+ export function withFakeRandom(provider, source = DEFAULT_ENTROPY) {
24
+ const sourceBytes = hexDecodeToBuffer(source);
25
+ let offset = 0;
26
+ function getRandomValues(buf) {
27
+ if (offset + buf.length > sourceBytes.length) {
28
+ throw new Error('not enough entropy');
29
+ }
30
+ buf.set(sourceBytes.subarray(offset, offset + buf.length));
31
+ offset += buf.length;
32
+ }
33
+ provider.randomFill = getRandomValues;
34
+ return provider;
35
+ }
36
+ export function useFakeMathRandom(source = DEFAULT_ENTROPY) {
37
+ beforeEach(() => {
38
+ const sourceBytes = hexDecodeToBuffer(source);
39
+ let offset = 0;
40
+ vi.spyOn(globalThis.Math, 'random').mockImplementation(() => {
41
+ const ret = dataViewFromBuffer(sourceBytes).getUint32(offset, true) / 0xffffffff;
42
+ offset += 4;
43
+ return ret;
44
+ });
45
+ });
46
+ afterEach(() => {
47
+ vi.spyOn(globalThis.Math, 'random').mockRestore();
48
+ });
49
+ }
50
+ export async function defaultTestCryptoProvider(source = DEFAULT_ENTROPY) {
51
+ const prov = withFakeRandom(defaultCryptoProviderFactory(), source);
52
+ await prov.initialize?.();
53
+ return prov;
54
+ }
55
+ export function testCryptoProvider(c) {
56
+ beforeAll(() => c.initialize?.());
57
+ function gzipSyncWrap(data) {
58
+ if (import.meta.env.TEST_ENV === 'browser') {
59
+ // @ts-expect-error fucking crutch because @jspm/core uses Buffer.isBuffer for some reason
60
+ data._isBuffer = true;
61
+ return new Uint8Array(gzipSync(data));
62
+ }
63
+ return gzipSync(data);
64
+ }
65
+ function inflateSyncWrap(data) {
66
+ if (import.meta.env.TEST_ENV === 'browser') {
67
+ // @ts-expect-error fucking crutch because @jspm/core uses Buffer.isBuffer for some reason
68
+ data._isBuffer = true;
69
+ return new Uint8Array(inflateSync(data));
70
+ }
71
+ return inflateSync(data);
72
+ }
73
+ it('should calculate sha1', () => {
74
+ expect(hexEncode(c.sha1(utf8EncodeToBuffer('')))).to.eq('da39a3ee5e6b4b0d3255bfef95601890afd80709');
75
+ expect(hexEncode(c.sha1(utf8EncodeToBuffer('hello')))).to.eq('aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d');
76
+ expect(hexEncode(c.sha1(hexDecodeToBuffer('aebb1f')))).to.eq('62849d15c5dea495916c5eea8dba5f9551288850');
77
+ });
78
+ it('should calculate sha256', () => {
79
+ expect(hexEncode(c.sha256(utf8EncodeToBuffer('')))).to.eq('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
80
+ expect(hexEncode(c.sha256(utf8EncodeToBuffer('hello')))).to.eq('2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824');
81
+ expect(hexEncode(c.sha256(hexDecodeToBuffer('aebb1f')))).to.eq('2d29658aba48f2b286fe8bbddb931b7ad297e5adb5b9a6fc3aab67ef7fbf4e80');
82
+ });
83
+ it('should calculate hmac-sha256', async () => {
84
+ const key = hexDecodeToBuffer('aaeeff');
85
+ expect(hexEncode(await c.hmacSha256(utf8EncodeToBuffer(''), key))).to.eq('642711307c9e4437df09d6ebaa6bdc1b3a810c7f15c50fd1d0f8d7d5490f44dd');
86
+ expect(hexEncode(await c.hmacSha256(utf8EncodeToBuffer('hello'), key))).to.eq('39b00bab151f9868e6501655c580b5542954711181243474d46b894703b1c1c2');
87
+ expect(hexEncode(await c.hmacSha256(hexDecodeToBuffer('aebb1f'), key))).to.eq('a3a7273871808711cab17aba14f58e96f63f3ccfc5097d206f0f00ead2c3dd35');
88
+ });
89
+ it('should derive pbkdf2 key', async () => {
90
+ expect(hexEncode(await c.pbkdf2(utf8EncodeToBuffer('pbkdf2 test'), utf8EncodeToBuffer('some salt'), 10))).to.eq('e43276cfa27f135f261cec8ddcf593fd74ec251038e459c165461f2308f3a7235e0744ee1aed9710b00db28d1a2112e20fea3601c60e770ac57ffe6b33ca8be1');
91
+ });
92
+ it('should encrypt and decrypt aes-ctr', () => {
93
+ let aes = c.createAesCtr(hexDecodeToBuffer('d450aae0bf0060a4af1044886b42a13f7c506b35255d134a7e87ab3f23a9493b'), hexDecodeToBuffer('0182de2bd789c295c3c6c875c5e9e190'), true);
94
+ const data = hexDecodeToBuffer('7baae571e4c2f4cfadb1931d5923aca7');
95
+ expect(hexEncode(aes.process(data))).eq('df5647dbb70bc393f2fb05b72f42286f');
96
+ expect(hexEncode(aes.process(data))).eq('3917147082672516b3177150129bc579');
97
+ expect(hexEncode(aes.process(data))).eq('2a7a9089270a5de45d5e3dd399cac725');
98
+ expect(hexEncode(aes.process(data))).eq('56d085217771398ac13583de4d677dd8');
99
+ expect(hexEncode(aes.process(data))).eq('cc639b488126cf36e79c4515e8012b92');
100
+ expect(hexEncode(aes.process(data))).eq('01384d100646cd562cc5586ec3f8f8c4');
101
+ aes.close?.();
102
+ aes = c.createAesCtr(hexDecodeToBuffer('d450aae0bf0060a4af1044886b42a13f7c506b35255d134a7e87ab3f23a9493b'), hexDecodeToBuffer('0182de2bd789c295c3c6c875c5e9e190'), false);
103
+ expect(hexEncode(aes.process(hexDecodeToBuffer('df5647dbb70bc393f2fb05b72f42286f')))).eq(hexEncode(data));
104
+ expect(hexEncode(aes.process(hexDecodeToBuffer('3917147082672516b3177150129bc579')))).eq(hexEncode(data));
105
+ expect(hexEncode(aes.process(hexDecodeToBuffer('2a7a9089270a5de45d5e3dd399cac725')))).eq(hexEncode(data));
106
+ expect(hexEncode(aes.process(hexDecodeToBuffer('56d085217771398ac13583de4d677dd8')))).eq(hexEncode(data));
107
+ expect(hexEncode(aes.process(hexDecodeToBuffer('cc639b488126cf36e79c4515e8012b92')))).eq(hexEncode(data));
108
+ expect(hexEncode(aes.process(hexDecodeToBuffer('01384d100646cd562cc5586ec3f8f8c4')))).eq(hexEncode(data));
109
+ aes.close?.();
110
+ });
111
+ it('should encrypt and decrypt aes-ige', () => {
112
+ const aes = c.createAesIge(hexDecodeToBuffer('5468697320697320616E20696D706C655468697320697320616E20696D706C65'), hexDecodeToBuffer('6D656E746174696F6E206F6620494745206D6F646520666F72204F70656E5353'));
113
+ expect(hexEncode(aes.encrypt(hexDecodeToBuffer('99706487a1cde613bc6de0b6f24b1c7aa448c8b9c3403e3467a8cad89340f53b')))).to.eq('792ea8ae577b1a66cb3bd92679b8030ca54ee631976bd3a04547fdcb4639fa69');
114
+ expect(hexEncode(aes.decrypt(hexDecodeToBuffer('792ea8ae577b1a66cb3bd92679b8030ca54ee631976bd3a04547fdcb4639fa69')))).to.eq('99706487a1cde613bc6de0b6f24b1c7aa448c8b9c3403e3467a8cad89340f53b');
115
+ });
116
+ it('should decompose PQ to prime factors P and Q', async () => {
117
+ const testFactorization = async (pq, p, q) => {
118
+ const [p1, q1] = await c.factorizePQ(hexDecodeToBuffer(pq));
119
+ expect(hexEncode(p1)).eq(p.toLowerCase());
120
+ expect(hexEncode(q1)).eq(q.toLowerCase());
121
+ };
122
+ // from samples at https://core.telegram.org/mtproto/samples-auth_key
123
+ await testFactorization('17ED48941A08F981', '494C553B', '53911073');
124
+ // random example
125
+ await testFactorization('14fcab4dfc861f45', '494c5c99', '494c778d');
126
+ },
127
+ // since PQ factorization relies on RNG, it may take a while (or may not!)
128
+ { timeout: 10000 });
129
+ it('should correctly gzip', () => {
130
+ const data = new Uint8Array(1000).fill(0x42);
131
+ const compressed = c.gzip(data, 100);
132
+ expect(compressed).not.toBeNull();
133
+ const decompressed = inflateSyncWrap(compressed);
134
+ expect(compressed.length).toBeLessThan(data.length);
135
+ expect(hexEncode(decompressed)).toEqual(hexEncode(data));
136
+ });
137
+ it('should correctly gunzip', () => {
138
+ const data = new Uint8Array(1000).fill(0x42);
139
+ const compressed = gzipSyncWrap(data);
140
+ const decompressed = c.gunzip(compressed);
141
+ expect(hexEncode(decompressed)).toEqual(hexEncode(data));
142
+ });
143
+ describe('randomBytes', () => {
144
+ it('should return exactly N bytes', () => {
145
+ expect(c.randomBytes(0).length).eq(0);
146
+ expect(c.randomBytes(5).length).eq(5);
147
+ expect(c.randomBytes(10).length).eq(10);
148
+ expect(c.randomBytes(256).length).eq(256);
149
+ });
150
+ it('should not be deterministic', () => {
151
+ expect([...c.randomBytes(8)]).not.eql([...c.randomBytes(8)]);
152
+ });
153
+ it('should use randomFill', () => {
154
+ const spy = vi.spyOn(c, 'randomFill');
155
+ c.randomBytes(8);
156
+ expect(spy).toHaveBeenCalled();
157
+ });
158
+ });
159
+ }
160
+ export function u8HexDecode(hex) {
161
+ const buf = hexDecodeToBuffer(hex);
162
+ // eslint-disable-next-line no-restricted-globals
163
+ if (import.meta.env.TEST_ENV === 'node' && Buffer.isBuffer(buf)) {
164
+ return new Uint8Array(buf);
165
+ }
166
+ return buf;
167
+ }
168
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/crypto.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'\nimport { gzipSync, inflateSync } from 'zlib'\n\nimport {\n dataViewFromBuffer,\n defaultCryptoProviderFactory,\n hexDecodeToBuffer,\n hexEncode,\n ICryptoProvider,\n utf8EncodeToBuffer,\n} from '@mtcute/core/utils.js'\n\n// some random 1024 bytes of entropy\nconst DEFAULT_ENTROPY = `\n29afd26df40fb8ed10b6b4ad6d56ef5df9453f88e6ee6adb6e0544ba635dc6a8a990c9b8b980c343936b33fa7f97bae025102532233abb269c489920ef99021b\n259ce3a2c964c5c8972b4a84ff96f3375a94b535a9468f2896e2080ac7a32ed58e910474a4b02415e07671cbb5bdd58a5dd26fd137c4c98b8c346571fae6ead3\n9dfd612bd6b480b6723433f5218e9d6e271591153fb3ffefc089f7e848d3f4633459fff66b33cf939e5655813149fa34be8625f9bc4814d1ee6cf40e4d0de229\n1aa22e68c8ad8cc698103734f9aaf79f2bdc052a787a7a9b3629d1ed38750f88cb0481c0ba30a9c611672f9a4d1dc02637abb4e98913ee810a3b152d3d75f25d\n7efdc263c08833569968b1771ebbe843d187e2c917d9ad8e8865e44b69f7b74d72ab86a4ef1891dce196ee11a7c9d7d8074fc0450e745bd3a827d77bb0820b90\n3055dc15f0abd897ea740a99606b64d28968d770b5e43492ddbf07a7c75104d3e522be9b72050c0fdae8412cdf49014be21105b87a06cb7202dd580387adc007\n6280d98b015a1a413819d817f007939d1490467a1ef85a345584c7e594bb729c12a1233f806e515e7088360219dfa109264310ba84777b93eb1ad3c40727a25a\na5d9cdd6748c6ab2ca0bd4daa2ba8225bce2b066a163bcacf05609fc84055bb86a4742c28addd7d7ab8d87b64cfde0b3f4b3bc8e05f3d0a1a2fadb294860e099\na10b3721b0d5b28918b8fb49a18a82a0fde6680a64ed915637805e35ffe8b2c1d4177ec10d10eaaf24425e0351b6a89e794944e1aa82eb5c0210a37da66cccac\n895398cf915a8aa141f611521fc258514a99c02721113942c66f2c9a8f9601ff0044a953d17a47b07ad1b5f8725cc020a1a5239be65db0a43d42c206903740f0\n27c3f749ecfff2e646570118cd54db2fec392b44d8eb8377309f3e4d164dbc0530914b117b9d278b06db8359d97442d4dcbcaff93cd9a08a6b06a5ba8725d0d7\n06b313a5d792be254d33e087b7a4fafcdf819941b9bec4c6057d4c050bd01eb243efd4e6b707281b127820a2b734c6d8f6b2131bf0b5b215c7a798ff3fe90ceb\nda91539fcc7b03d2b8b1381bd6023fff20278344ad944d364ba684842db3901c346335f0d455eda414f99c1e794a86aa3a90bcc6e085eecb0b4bf61198d16ed3\n89cfa495f977a37a51502b2f60649f2efd7d89c757b6366776ba4c0612017bf1fbfc682dd62e9960d39cbea854d2dcc708b1db5d268192954d13ee72c0bb1bd8\n558a3cf3b02b1cd795b40f7a57780391bb8724883d3f7764846c3823e165b3f8c025f59d896905f9a955478586ce57f820d958a01aa59a4cace7ecdf125df334\nfa3de8e50aac96c1275591a1221c32a60a1513370a33a228e00894341b10cf44a6ae6ac250d17a364e956ab1a17b068df3fb2d5b5a672d8a409eeb8b6ca1ade6\n`.replace(/\\s/g, '')\n\nexport function withFakeRandom(provider: ICryptoProvider, source = DEFAULT_ENTROPY): ICryptoProvider {\n const sourceBytes = hexDecodeToBuffer(source)\n let offset = 0\n\n function getRandomValues(buf: Uint8Array) {\n if (offset + buf.length > sourceBytes.length) {\n throw new Error('not enough entropy')\n }\n\n buf.set(sourceBytes.subarray(offset, offset + buf.length))\n offset += buf.length\n }\n\n provider.randomFill = getRandomValues\n\n return provider\n}\n\nexport function useFakeMathRandom(source = DEFAULT_ENTROPY): void {\n beforeEach(() => {\n const sourceBytes = hexDecodeToBuffer(source)\n let offset = 0\n\n vi.spyOn(globalThis.Math, 'random').mockImplementation(() => {\n const ret = dataViewFromBuffer(sourceBytes).getUint32(offset, true) / 0xffffffff\n offset += 4\n\n return ret\n })\n })\n afterEach(() => {\n vi.spyOn(globalThis.Math, 'random').mockRestore()\n })\n}\n\nexport async function defaultTestCryptoProvider(source = DEFAULT_ENTROPY): Promise<ICryptoProvider> {\n const prov = withFakeRandom(defaultCryptoProviderFactory(), source)\n await prov.initialize?.()\n\n return prov\n}\n\nexport function testCryptoProvider(c: ICryptoProvider): void {\n beforeAll(() => c.initialize?.())\n\n function gzipSyncWrap(data: Uint8Array) {\n if (import.meta.env.TEST_ENV === 'browser') {\n // @ts-expect-error fucking crutch because @jspm/core uses Buffer.isBuffer for some reason\n data._isBuffer = true\n\n return new Uint8Array(gzipSync(data))\n }\n\n return gzipSync(data)\n }\n\n function inflateSyncWrap(data: Uint8Array) {\n if (import.meta.env.TEST_ENV === 'browser') {\n // @ts-expect-error fucking crutch because @jspm/core uses Buffer.isBuffer for some reason\n data._isBuffer = true\n\n return new Uint8Array(inflateSync(data))\n }\n\n return inflateSync(data)\n }\n\n it('should calculate sha1', () => {\n expect(hexEncode(c.sha1(utf8EncodeToBuffer('')))).to.eq('da39a3ee5e6b4b0d3255bfef95601890afd80709')\n expect(hexEncode(c.sha1(utf8EncodeToBuffer('hello')))).to.eq('aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d')\n expect(hexEncode(c.sha1(hexDecodeToBuffer('aebb1f')))).to.eq('62849d15c5dea495916c5eea8dba5f9551288850')\n })\n\n it('should calculate sha256', () => {\n expect(hexEncode(c.sha256(utf8EncodeToBuffer('')))).to.eq(\n 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',\n )\n expect(hexEncode(c.sha256(utf8EncodeToBuffer('hello')))).to.eq(\n '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824',\n )\n expect(hexEncode(c.sha256(hexDecodeToBuffer('aebb1f')))).to.eq(\n '2d29658aba48f2b286fe8bbddb931b7ad297e5adb5b9a6fc3aab67ef7fbf4e80',\n )\n })\n\n it('should calculate hmac-sha256', async () => {\n const key = hexDecodeToBuffer('aaeeff')\n\n expect(hexEncode(await c.hmacSha256(utf8EncodeToBuffer(''), key))).to.eq(\n '642711307c9e4437df09d6ebaa6bdc1b3a810c7f15c50fd1d0f8d7d5490f44dd',\n )\n expect(hexEncode(await c.hmacSha256(utf8EncodeToBuffer('hello'), key))).to.eq(\n '39b00bab151f9868e6501655c580b5542954711181243474d46b894703b1c1c2',\n )\n expect(hexEncode(await c.hmacSha256(hexDecodeToBuffer('aebb1f'), key))).to.eq(\n 'a3a7273871808711cab17aba14f58e96f63f3ccfc5097d206f0f00ead2c3dd35',\n )\n })\n\n it('should derive pbkdf2 key', async () => {\n expect(hexEncode(await c.pbkdf2(utf8EncodeToBuffer('pbkdf2 test'), utf8EncodeToBuffer('some salt'), 10))).to.eq(\n 'e43276cfa27f135f261cec8ddcf593fd74ec251038e459c165461f2308f3a7235e0744ee1aed9710b00db28d1a2112e20fea3601c60e770ac57ffe6b33ca8be1',\n )\n })\n\n it('should encrypt and decrypt aes-ctr', () => {\n let aes = c.createAesCtr(\n hexDecodeToBuffer('d450aae0bf0060a4af1044886b42a13f7c506b35255d134a7e87ab3f23a9493b'),\n hexDecodeToBuffer('0182de2bd789c295c3c6c875c5e9e190'),\n true,\n )\n\n const data = hexDecodeToBuffer('7baae571e4c2f4cfadb1931d5923aca7')\n expect(hexEncode(aes.process(data))).eq('df5647dbb70bc393f2fb05b72f42286f')\n expect(hexEncode(aes.process(data))).eq('3917147082672516b3177150129bc579')\n expect(hexEncode(aes.process(data))).eq('2a7a9089270a5de45d5e3dd399cac725')\n expect(hexEncode(aes.process(data))).eq('56d085217771398ac13583de4d677dd8')\n expect(hexEncode(aes.process(data))).eq('cc639b488126cf36e79c4515e8012b92')\n expect(hexEncode(aes.process(data))).eq('01384d100646cd562cc5586ec3f8f8c4')\n\n aes.close?.()\n aes = c.createAesCtr(\n hexDecodeToBuffer('d450aae0bf0060a4af1044886b42a13f7c506b35255d134a7e87ab3f23a9493b'),\n hexDecodeToBuffer('0182de2bd789c295c3c6c875c5e9e190'),\n false,\n )\n\n expect(hexEncode(aes.process(hexDecodeToBuffer('df5647dbb70bc393f2fb05b72f42286f')))).eq(hexEncode(data))\n expect(hexEncode(aes.process(hexDecodeToBuffer('3917147082672516b3177150129bc579')))).eq(hexEncode(data))\n expect(hexEncode(aes.process(hexDecodeToBuffer('2a7a9089270a5de45d5e3dd399cac725')))).eq(hexEncode(data))\n expect(hexEncode(aes.process(hexDecodeToBuffer('56d085217771398ac13583de4d677dd8')))).eq(hexEncode(data))\n expect(hexEncode(aes.process(hexDecodeToBuffer('cc639b488126cf36e79c4515e8012b92')))).eq(hexEncode(data))\n expect(hexEncode(aes.process(hexDecodeToBuffer('01384d100646cd562cc5586ec3f8f8c4')))).eq(hexEncode(data))\n\n aes.close?.()\n })\n\n it('should encrypt and decrypt aes-ige', () => {\n const aes = c.createAesIge(\n hexDecodeToBuffer('5468697320697320616E20696D706C655468697320697320616E20696D706C65'),\n hexDecodeToBuffer('6D656E746174696F6E206F6620494745206D6F646520666F72204F70656E5353'),\n )\n expect(\n hexEncode(\n aes.encrypt(hexDecodeToBuffer('99706487a1cde613bc6de0b6f24b1c7aa448c8b9c3403e3467a8cad89340f53b')),\n ),\n ).to.eq('792ea8ae577b1a66cb3bd92679b8030ca54ee631976bd3a04547fdcb4639fa69')\n expect(\n hexEncode(\n aes.decrypt(hexDecodeToBuffer('792ea8ae577b1a66cb3bd92679b8030ca54ee631976bd3a04547fdcb4639fa69')),\n ),\n ).to.eq('99706487a1cde613bc6de0b6f24b1c7aa448c8b9c3403e3467a8cad89340f53b')\n })\n\n it(\n 'should decompose PQ to prime factors P and Q',\n async () => {\n const testFactorization = async (pq: string, p: string, q: string) => {\n const [p1, q1] = await c.factorizePQ(hexDecodeToBuffer(pq))\n expect(hexEncode(p1)).eq(p.toLowerCase())\n expect(hexEncode(q1)).eq(q.toLowerCase())\n }\n\n // from samples at https://core.telegram.org/mtproto/samples-auth_key\n await testFactorization('17ED48941A08F981', '494C553B', '53911073')\n // random example\n await testFactorization('14fcab4dfc861f45', '494c5c99', '494c778d')\n },\n // since PQ factorization relies on RNG, it may take a while (or may not!)\n { timeout: 10000 },\n )\n\n it('should correctly gzip', () => {\n const data = new Uint8Array(1000).fill(0x42)\n\n const compressed = c.gzip(data, 100)\n\n expect(compressed).not.toBeNull()\n\n const decompressed = inflateSyncWrap(compressed!)\n\n expect(compressed!.length).toBeLessThan(data.length)\n expect(hexEncode(decompressed)).toEqual(hexEncode(data))\n })\n\n it('should correctly gunzip', () => {\n const data = new Uint8Array(1000).fill(0x42)\n\n const compressed = gzipSyncWrap(data)\n const decompressed = c.gunzip(compressed)\n\n expect(hexEncode(decompressed)).toEqual(hexEncode(data))\n })\n\n describe('randomBytes', () => {\n it('should return exactly N bytes', () => {\n expect(c.randomBytes(0).length).eq(0)\n expect(c.randomBytes(5).length).eq(5)\n expect(c.randomBytes(10).length).eq(10)\n expect(c.randomBytes(256).length).eq(256)\n })\n\n it('should not be deterministic', () => {\n expect([...c.randomBytes(8)]).not.eql([...c.randomBytes(8)])\n })\n\n it('should use randomFill', () => {\n const spy = vi.spyOn(c, 'randomFill')\n c.randomBytes(8)\n\n expect(spy).toHaveBeenCalled()\n })\n })\n}\n\nexport function u8HexDecode(hex: string) {\n const buf = hexDecodeToBuffer(hex)\n\n // eslint-disable-next-line no-restricted-globals\n if (import.meta.env.TEST_ENV === 'node' && Buffer.isBuffer(buf)) {\n return new Uint8Array(buf)\n }\n\n return buf\n}\n"]}
package/esm/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from './client.js';
2
+ export * from './crypto.js';
2
3
  export * from './storage.js';
4
+ export * from './storage-test.js';
3
5
  export * from './stub.js';
4
6
  export * from './transport.js';
5
7
  export * from './types.js';
package/esm/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from './client.js';
2
+ export * from './crypto.js';
2
3
  export * from './storage.js';
4
+ export * from './storage-test.js';
3
5
  export * from './stub.js';
4
6
  export * from './transport.js';
5
7
  export * from './types.js';
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA","sourcesContent":["export * from './client.js'\nexport * from './storage.js'\nexport * from './stub.js'\nexport * from './transport.js'\nexport * from './types.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,mBAAmB,CAAA;AACjC,cAAc,WAAW,CAAA;AACzB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA","sourcesContent":["export * from './client.js'\nexport * from './crypto.js'\nexport * from './storage.js'\nexport * from './storage-test.js'\nexport * from './stub.js'\nexport * from './transport.js'\nexport * from './types.js'\n"]}
package/esm/schema.js CHANGED
@@ -1,4 +1,5 @@
1
- import { createRequire } from 'module';
1
+ import * as schema_ from '@mtcute/tl/api-schema.json' assert { type: 'json' };
2
+ const schema = ('default' in schema_ ? schema_.default : schema_);
2
3
  let _cachedEntriesMap = null;
3
4
  let _cachedUnionsMap = null;
4
5
  /** @internal */
@@ -9,7 +10,6 @@ export function getEntriesMap() {
9
10
  unions: _cachedUnionsMap,
10
11
  };
11
12
  }
12
- const schema = createRequire(import.meta.url)('@mtcute/tl/api-schema.json');
13
13
  _cachedEntriesMap = new Map();
14
14
  _cachedUnionsMap = new Map();
15
15
  let entry;
package/esm/schema.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AAItC,IAAI,iBAAiB,GAAgC,IAAI,CAAA;AACzD,IAAI,gBAAgB,GAAkC,IAAI,CAAA;AAE1D,gBAAgB;AAChB,MAAM,UAAU,aAAa;IACzB,IAAI,iBAAiB,EAAE;QACnB,OAAO;YACH,OAAO,EAAE,iBAAiB;YAC1B,MAAM,EAAE,gBAAiB;SAC5B,CAAA;KACJ;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,4BAA4B,CAEzE,CAAA;IAED,iBAAiB,GAAG,IAAI,GAAG,EAAE,CAAA;IAC7B,gBAAgB,GAAG,IAAI,GAAG,EAAE,CAAA;IAE5B,IAAI,KAAc,CAAA;IAElB,KAAK,KAAK,IAAI,MAAM,CAAC,CAAC,EAAE;QACpB,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QAExC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;YACnC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;SACvC;QACD,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;KAChD;IAED,OAAO;QACH,OAAO,EAAE,iBAAiB;QAC1B,MAAM,EAAE,gBAAgB;KAC3B,CAAA;AACL,CAAC","sourcesContent":["import { createRequire } from 'module'\n\nimport type { TlEntry } from '@mtcute/tl-utils'\n\nlet _cachedEntriesMap: Map<string, TlEntry> | null = null\nlet _cachedUnionsMap: Map<string, TlEntry[]> | null = null\n\n/** @internal */\nexport function getEntriesMap() {\n if (_cachedEntriesMap) {\n return {\n entries: _cachedEntriesMap,\n unions: _cachedUnionsMap!,\n }\n }\n\n const schema = createRequire(import.meta.url)('@mtcute/tl/api-schema.json') as {\n e: TlEntry[]\n }\n\n _cachedEntriesMap = new Map()\n _cachedUnionsMap = new Map()\n\n let entry: TlEntry\n\n for (entry of schema.e) {\n _cachedEntriesMap.set(entry.name, entry)\n\n if (!_cachedUnionsMap.has(entry.type)) {\n _cachedUnionsMap.set(entry.type, [])\n }\n _cachedUnionsMap.get(entry.type)!.push(entry)\n }\n\n return {\n entries: _cachedEntriesMap,\n unions: _cachedUnionsMap,\n }\n}\n"]}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,4BAA4B,CAAC,SAAS,IAAI,EAAE,MAAM,EAAE,CAAA;AAE7E,MAAM,MAAM,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAqB,CAAA;AAIrF,IAAI,iBAAiB,GAAgC,IAAI,CAAA;AACzD,IAAI,gBAAgB,GAAkC,IAAI,CAAA;AAE1D,gBAAgB;AAChB,MAAM,UAAU,aAAa;IACzB,IAAI,iBAAiB,EAAE;QACnB,OAAO;YACH,OAAO,EAAE,iBAAiB;YAC1B,MAAM,EAAE,gBAAiB;SAC5B,CAAA;KACJ;IAED,iBAAiB,GAAG,IAAI,GAAG,EAAE,CAAA;IAC7B,gBAAgB,GAAG,IAAI,GAAG,EAAE,CAAA;IAE5B,IAAI,KAAc,CAAA;IAElB,KAAK,KAAK,IAAI,MAAM,CAAC,CAAC,EAAE;QACpB,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QAExC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;YACnC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;SACvC;QACD,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;KAChD;IAED,OAAO;QACH,OAAO,EAAE,iBAAiB;QAC1B,MAAM,EAAE,gBAAgB;KAC3B,CAAA;AACL,CAAC","sourcesContent":["import * as schema_ from '@mtcute/tl/api-schema.json' assert { type: 'json' }\n\nconst schema = ('default' in schema_ ? schema_.default : schema_) as { e: TlEntry[] }\n\nimport type { TlEntry } from '@mtcute/tl-utils'\n\nlet _cachedEntriesMap: Map<string, TlEntry> | null = null\nlet _cachedUnionsMap: Map<string, TlEntry[]> | null = null\n\n/** @internal */\nexport function getEntriesMap() {\n if (_cachedEntriesMap) {\n return {\n entries: _cachedEntriesMap,\n unions: _cachedUnionsMap!,\n }\n }\n\n _cachedEntriesMap = new Map()\n _cachedUnionsMap = new Map()\n\n let entry: TlEntry\n\n for (entry of schema.e) {\n _cachedEntriesMap.set(entry.name, entry)\n\n if (!_cachedUnionsMap.has(entry.type)) {\n _cachedUnionsMap.set(entry.type, [])\n }\n _cachedUnionsMap.get(entry.type)!.push(entry)\n }\n\n return {\n entries: _cachedEntriesMap,\n unions: _cachedUnionsMap,\n }\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { ITelegramStorage, MaybeAsync } from '@mtcute/core';
2
+ import { Logger, TlReaderMap, TlWriterMap } from '@mtcute/core/utils.js';
3
+ export declare const stubPeerUser: ITelegramStorage.PeerInfo;
4
+ export declare function testStorage<T extends ITelegramStorage>(s: T, params?: {
5
+ skipEntityOverwrite?: boolean;
6
+ customTests?: (s: T) => void;
7
+ }): void;
8
+ interface IStateStorage {
9
+ setup?(log: Logger, readerMap: TlReaderMap, writerMap: TlWriterMap): void;
10
+ load?(): MaybeAsync<void>;
11
+ save?(): MaybeAsync<void>;
12
+ destroy?(): MaybeAsync<void>;
13
+ reset(): MaybeAsync<void>;
14
+ getState(key: string): MaybeAsync<unknown>;
15
+ setState(key: string, state: unknown, ttl?: number): MaybeAsync<void>;
16
+ deleteState(key: string): MaybeAsync<void>;
17
+ getCurrentScene(key: string): MaybeAsync<string | null>;
18
+ setCurrentScene(key: string, scene: string, ttl?: number): MaybeAsync<void>;
19
+ deleteCurrentScene(key: string): MaybeAsync<void>;
20
+ getRateLimit(key: string, limit: number, window: number): MaybeAsync<[number, number]>;
21
+ resetRateLimit(key: string): MaybeAsync<void>;
22
+ }
23
+ export declare function testStateStorage(s: IStateStorage): void;
24
+ export {};