morok-bot-sdk 1.0.1

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 (96) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +602 -0
  3. package/README.ru.md +602 -0
  4. package/dist/bot.d.ts +232 -0
  5. package/dist/bot.d.ts.map +1 -0
  6. package/dist/bot.js +558 -0
  7. package/dist/bot.js.map +1 -0
  8. package/dist/crypto/channel-cipher.d.ts +32 -0
  9. package/dist/crypto/channel-cipher.d.ts.map +1 -0
  10. package/dist/crypto/channel-cipher.js +77 -0
  11. package/dist/crypto/channel-cipher.js.map +1 -0
  12. package/dist/crypto/channel-key-store.d.ts +37 -0
  13. package/dist/crypto/channel-key-store.d.ts.map +1 -0
  14. package/dist/crypto/channel-key-store.js +149 -0
  15. package/dist/crypto/channel-key-store.js.map +1 -0
  16. package/dist/crypto/cross-signing.d.ts +57 -0
  17. package/dist/crypto/cross-signing.d.ts.map +1 -0
  18. package/dist/crypto/cross-signing.js +111 -0
  19. package/dist/crypto/cross-signing.js.map +1 -0
  20. package/dist/crypto/file-cipher.d.ts +36 -0
  21. package/dist/crypto/file-cipher.d.ts.map +1 -0
  22. package/dist/crypto/file-cipher.js +61 -0
  23. package/dist/crypto/file-cipher.js.map +1 -0
  24. package/dist/crypto/group-secret-cipher.d.ts +49 -0
  25. package/dist/crypto/group-secret-cipher.d.ts.map +1 -0
  26. package/dist/crypto/group-secret-cipher.js +69 -0
  27. package/dist/crypto/group-secret-cipher.js.map +1 -0
  28. package/dist/crypto/group-secret-store.d.ts +35 -0
  29. package/dist/crypto/group-secret-store.d.ts.map +1 -0
  30. package/dist/crypto/group-secret-store.js +149 -0
  31. package/dist/crypto/group-secret-store.js.map +1 -0
  32. package/dist/crypto/signal.d.ts +81 -0
  33. package/dist/crypto/signal.d.ts.map +1 -0
  34. package/dist/crypto/signal.js +125 -0
  35. package/dist/crypto/signal.js.map +1 -0
  36. package/dist/crypto/stores.d.ts +130 -0
  37. package/dist/crypto/stores.d.ts.map +1 -0
  38. package/dist/crypto/stores.js +314 -0
  39. package/dist/crypto/stores.js.map +1 -0
  40. package/dist/flow/attachments.d.ts +110 -0
  41. package/dist/flow/attachments.d.ts.map +1 -0
  42. package/dist/flow/attachments.js +409 -0
  43. package/dist/flow/attachments.js.map +1 -0
  44. package/dist/flow/conv-cache.d.ts +36 -0
  45. package/dist/flow/conv-cache.d.ts.map +1 -0
  46. package/dist/flow/conv-cache.js +84 -0
  47. package/dist/flow/conv-cache.js.map +1 -0
  48. package/dist/flow/direct.d.ts +109 -0
  49. package/dist/flow/direct.d.ts.map +1 -0
  50. package/dist/flow/direct.js +346 -0
  51. package/dist/flow/direct.js.map +1 -0
  52. package/dist/flow/groups.d.ts +146 -0
  53. package/dist/flow/groups.d.ts.map +1 -0
  54. package/dist/flow/groups.js +768 -0
  55. package/dist/flow/groups.js.map +1 -0
  56. package/dist/flow/prekeys.d.ts +45 -0
  57. package/dist/flow/prekeys.d.ts.map +1 -0
  58. package/dist/flow/prekeys.js +111 -0
  59. package/dist/flow/prekeys.js.map +1 -0
  60. package/dist/flow/receive.d.ts +125 -0
  61. package/dist/flow/receive.d.ts.map +1 -0
  62. package/dist/flow/receive.js +773 -0
  63. package/dist/flow/receive.js.map +1 -0
  64. package/dist/index.d.ts +15 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +6 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/morokbot-file.d.ts +14 -0
  69. package/dist/morokbot-file.d.ts.map +1 -0
  70. package/dist/morokbot-file.js +88 -0
  71. package/dist/morokbot-file.js.map +1 -0
  72. package/dist/ratelimit.d.ts +40 -0
  73. package/dist/ratelimit.d.ts.map +1 -0
  74. package/dist/ratelimit.js +76 -0
  75. package/dist/ratelimit.js.map +1 -0
  76. package/dist/sessions.d.ts +34 -0
  77. package/dist/sessions.d.ts.map +1 -0
  78. package/dist/sessions.js +69 -0
  79. package/dist/sessions.js.map +1 -0
  80. package/dist/state-lock.d.ts +17 -0
  81. package/dist/state-lock.d.ts.map +1 -0
  82. package/dist/state-lock.js +66 -0
  83. package/dist/state-lock.js.map +1 -0
  84. package/dist/transport/http.d.ts +48 -0
  85. package/dist/transport/http.d.ts.map +1 -0
  86. package/dist/transport/http.js +112 -0
  87. package/dist/transport/http.js.map +1 -0
  88. package/dist/transport/ws.d.ts +65 -0
  89. package/dist/transport/ws.d.ts.map +1 -0
  90. package/dist/transport/ws.js +219 -0
  91. package/dist/transport/ws.js.map +1 -0
  92. package/dist/types.d.ts +254 -0
  93. package/dist/types.d.ts.map +1 -0
  94. package/dist/types.js +2 -0
  95. package/dist/types.js.map +1 -0
  96. package/package.json +59 -0
@@ -0,0 +1,409 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { generateAesKey, exportKeyRaw, importKeyForDecrypt, aesGcmEncrypt, aesGcmDecrypt, packSealed, unpackSealed, chunkAad, AES_IV_BYTES, AES_TAG_BYTES, } from '../crypto/file-cipher.js';
3
+ export const SINGLE_UPLOAD_PLAINTEXT_LIMIT = 50 * 1024 * 1024;
4
+ export const MAX_PLAINTEXT_BYTES = 5 * 1024 * 1024 * 1024;
5
+ const WIRE_CHUNK_BUDGET = 5 * 1024 * 1024 - 4096;
6
+ const CHUNK_PLAINTEXT_SIZE = WIRE_CHUNK_BUDGET - AES_IV_BYTES - AES_TAG_BYTES;
7
+ const MAX_CHUNK_COUNT = 10_000;
8
+ const CHUNK_UPLOAD_CONCURRENCY = 4;
9
+ export class UploadRejectedError extends Error {
10
+ code;
11
+ status;
12
+ constructor(message, code, status) {
13
+ super(message);
14
+ this.code = code;
15
+ this.status = status;
16
+ this.name = 'UploadRejectedError';
17
+ }
18
+ }
19
+ function asUploadError(err) {
20
+ const e = err;
21
+ const code = typeof e?.response?.data?.code === 'string' ? e.response.data.code : undefined;
22
+ if (code) {
23
+ const msg = typeof e.response?.data?.error === 'string'
24
+ ? e.response.data.error
25
+ : err instanceof Error ? err.message : code;
26
+ return new UploadRejectedError(`upload rejected: ${msg} (${code})`, code, e.response?.status);
27
+ }
28
+ return err;
29
+ }
30
+ export async function uploadAttachment(http, plaintext, opts = {}, logger) {
31
+ if (plaintext.byteLength === 0) {
32
+ throw new Error('uploadAttachment: empty attachment');
33
+ }
34
+ if (plaintext.byteLength > MAX_PLAINTEXT_BYTES) {
35
+ throw new Error(`uploadAttachment: plaintext is ${plaintext.byteLength} bytes; max for direct upload is ` +
36
+ `${MAX_PLAINTEXT_BYTES} (Quickshare / P2P is not in v0.2 scope)`);
37
+ }
38
+ try {
39
+ if (plaintext.byteLength <= SINGLE_UPLOAD_PLAINTEXT_LIMIT) {
40
+ return await uploadSingle(http, plaintext, opts, logger);
41
+ }
42
+ return await uploadChunked(http, plaintext, opts, logger);
43
+ }
44
+ catch (err) {
45
+ throw asUploadError(err);
46
+ }
47
+ }
48
+ async function uploadSingle(http, plaintext, opts, logger) {
49
+ const key = await generateAesKey();
50
+ const sealed = await aesGcmEncrypt(key, plaintext);
51
+ const keyRaw = await exportKeyRaw(key);
52
+ const packed = packSealed(sealed);
53
+ const ciphertextSha256 = createHash('sha256').update(packed).digest('hex');
54
+ const plaintextSha256 = createHash('sha256').update(plaintext).digest('hex');
55
+ const mime = opts.mime ?? 'application/octet-stream';
56
+ const filename = opts.filename;
57
+ const dotIdx = filename ? filename.lastIndexOf('.') : -1;
58
+ const fileExt = filename && dotIdx > 0 && dotIdx < filename.length - 1
59
+ ? filename.slice(dotIdx + 1).toLowerCase().slice(0, 16)
60
+ : '';
61
+ const headers = {
62
+ 'Content-Type': 'application/octet-stream',
63
+ 'x-file-sha256': ciphertextSha256,
64
+ 'x-plaintext-sha256': plaintextSha256,
65
+ 'x-file-mime': mime,
66
+ };
67
+ if (fileExt)
68
+ headers['x-file-extension'] = fileExt;
69
+ if (opts.noteMedia)
70
+ headers['x-note-media'] = '1';
71
+ logger?.debug({ size: plaintext.byteLength, mime, noteMedia: opts.noteMedia ?? false }, '[attachments] uploading');
72
+ const res = await http.post('/files/upload', Buffer.from(packed.buffer, packed.byteOffset, packed.byteLength), {
73
+ headers,
74
+ timeout: 5 * 60 * 1000,
75
+ });
76
+ if (typeof res.data?.fileId !== 'number' || typeof res.data?.sha256 !== 'string') {
77
+ throw new Error(`uploadAttachment: malformed server response (status=${res.status})`);
78
+ }
79
+ if (res.data.sha256 !== ciphertextSha256) {
80
+ throw new Error(`uploadAttachment: server returned sha256 mismatch (expected ${ciphertextSha256}, got ${res.data.sha256})`);
81
+ }
82
+ return {
83
+ fileId: res.data.fileId,
84
+ sha256: res.data.sha256,
85
+ key: Buffer.from(keyRaw).toString('base64'),
86
+ iv: Buffer.from(sealed.iv).toString('base64'),
87
+ size: plaintext.byteLength,
88
+ mime,
89
+ ...(filename ? { name: filename } : {}),
90
+ };
91
+ }
92
+ async function abortChunkedUpload(http, uploadId) {
93
+ if (uploadId.length < 8)
94
+ return;
95
+ try {
96
+ await http.post('/files/upload/abort', { uploadId });
97
+ }
98
+ catch { }
99
+ }
100
+ async function uploadChunked(http, plaintext, opts, logger) {
101
+ const totalSize = plaintext.byteLength;
102
+ const totalChunks = Math.ceil(totalSize / CHUNK_PLAINTEXT_SIZE);
103
+ if (totalChunks < 2) {
104
+ throw new Error('uploadChunked: requires > 1 chunk; use uploadSingle instead');
105
+ }
106
+ if (totalChunks > MAX_CHUNK_COUNT) {
107
+ throw new Error(`uploadChunked: ${totalChunks} chunks exceeds server cap of ${MAX_CHUNK_COUNT}`);
108
+ }
109
+ const mime = opts.mime ?? 'application/octet-stream';
110
+ const filename = opts.filename;
111
+ const dotIdx = filename ? filename.lastIndexOf('.') : -1;
112
+ const fileExt = filename && dotIdx > 0 && dotIdx < filename.length - 1
113
+ ? filename.slice(dotIdx + 1).toLowerCase().slice(0, 16)
114
+ : null;
115
+ const VT_HASH_MAX = 200 * 1024 * 1024;
116
+ const plaintextSha256 = totalSize <= VT_HASH_MAX
117
+ ? createHash('sha256').update(plaintext).digest('hex')
118
+ : null;
119
+ const initRes = await http.post('/files/upload/init', {
120
+ totalSize,
121
+ totalChunks,
122
+ mimeType: mime,
123
+ fileExtension: fileExt,
124
+ plaintextSha256,
125
+ ...(opts.noteMedia ? { noteMedia: true } : {}),
126
+ });
127
+ const uploadId = initRes.data?.uploadId;
128
+ if (typeof uploadId !== 'string' || uploadId.length < 8) {
129
+ throw new Error('uploadChunked: malformed /files/upload/init response');
130
+ }
131
+ const key = await generateAesKey();
132
+ const keyRaw = await exportKeyRaw(key);
133
+ logger?.debug({ uploadId, totalSize, totalChunks, chunkConcurrency: CHUNK_UPLOAD_CONCURRENCY }, '[attachments] chunked upload begin');
134
+ const abort = new AbortController();
135
+ let nextIndex = 0;
136
+ let firstError = null;
137
+ const inflight = [];
138
+ const runChunk = async (i) => {
139
+ const start = i * CHUNK_PLAINTEXT_SIZE;
140
+ const end = Math.min(start + CHUNK_PLAINTEXT_SIZE, totalSize);
141
+ const slice = plaintext.subarray(start, end);
142
+ const sealed = await aesGcmEncrypt(key, slice, chunkAad(i, totalChunks));
143
+ const packed = packSealed(sealed);
144
+ const chunkSha = createHash('sha256').update(packed).digest('hex');
145
+ await http.post('/files/upload/chunk', Buffer.from(packed.buffer, packed.byteOffset, packed.byteLength), {
146
+ headers: {
147
+ 'Content-Type': 'application/octet-stream',
148
+ 'x-upload-id': uploadId,
149
+ 'x-chunk-index': String(i),
150
+ 'x-chunk-sha256': chunkSha,
151
+ },
152
+ timeout: 10 * 60 * 1000,
153
+ signal: abort.signal,
154
+ });
155
+ };
156
+ const worker = async () => {
157
+ while (!firstError) {
158
+ const myIndex = nextIndex++;
159
+ if (myIndex >= totalChunks)
160
+ return;
161
+ try {
162
+ await runChunk(myIndex);
163
+ }
164
+ catch (err) {
165
+ if (!firstError) {
166
+ firstError = err;
167
+ abort.abort();
168
+ }
169
+ return;
170
+ }
171
+ }
172
+ };
173
+ for (let w = 0; w < Math.min(CHUNK_UPLOAD_CONCURRENCY, totalChunks); w++) {
174
+ inflight.push(worker());
175
+ }
176
+ await Promise.all(inflight);
177
+ if (firstError) {
178
+ void abortChunkedUpload(http, uploadId);
179
+ throw firstError;
180
+ }
181
+ let completeRes;
182
+ try {
183
+ completeRes = await http.post('/files/upload/complete', { uploadId }, { timeout: 5 * 60 * 1000 });
184
+ }
185
+ catch (err) {
186
+ void abortChunkedUpload(http, uploadId);
187
+ throw err;
188
+ }
189
+ const c = completeRes.data;
190
+ if (typeof c?.fileId !== 'number' || typeof c?.sha256 !== 'string') {
191
+ void abortChunkedUpload(http, uploadId);
192
+ throw new Error('uploadChunked: malformed /files/upload/complete response');
193
+ }
194
+ logger?.info({ fileId: c.fileId, sha256: c.sha256, totalSize, totalChunks }, '[attachments] chunked upload complete');
195
+ return {
196
+ fileId: c.fileId,
197
+ sha256: c.sha256,
198
+ key: Buffer.from(keyRaw).toString('base64'),
199
+ iv: '',
200
+ size: totalSize,
201
+ mime,
202
+ chunked: true,
203
+ totalChunks,
204
+ ...(filename ? { name: filename } : {}),
205
+ };
206
+ }
207
+ export async function downloadAttachment(http, ref, logger) {
208
+ if (!/^[a-f0-9]{64}$/.test(ref.sha256)) {
209
+ throw new Error(`downloadAttachment: invalid sha256 ${ref.sha256}`);
210
+ }
211
+ if (ref.size <= 0) {
212
+ throw new Error(`downloadAttachment: ref.size must be > 0 (got ${ref.size})`);
213
+ }
214
+ if (ref.size > MAX_PLAINTEXT_BYTES) {
215
+ throw new Error(`downloadAttachment: ref.size ${ref.size} exceeds 5 GB ceiling`);
216
+ }
217
+ const keyRaw = Buffer.from(ref.key, 'base64');
218
+ if (keyRaw.byteLength !== 32) {
219
+ throw new Error(`downloadAttachment: ref.key decodes to ${keyRaw.byteLength} bytes; expected 32`);
220
+ }
221
+ const maxChunks = Math.ceil(ref.size / CHUNK_PLAINTEXT_SIZE) + 1;
222
+ const ciphertextCap = ref.size + maxChunks * (AES_IV_BYTES + AES_TAG_BYTES) + WIRE_CHUNK_BUDGET;
223
+ const ciphertextBytes = await fetchCiphertextBytes(http, ref.sha256, ciphertextCap);
224
+ const key = await importKeyForDecrypt(keyRaw);
225
+ if (ref.chunked === true) {
226
+ return downloadChunked(ref, ciphertextBytes, key, logger);
227
+ }
228
+ return downloadSingle(ref, ciphertextBytes, key, logger);
229
+ }
230
+ async function downloadSingle(ref, ciphertextBytes, key, logger) {
231
+ const ivBytes = Buffer.from(ref.iv, 'base64');
232
+ if (ivBytes.byteLength !== 12) {
233
+ throw new Error(`downloadAttachment: ref.iv decodes to ${ivBytes.byteLength} bytes; expected 12`);
234
+ }
235
+ const sealed = unpackSealed(ciphertextBytes);
236
+ if (Buffer.compare(Buffer.from(sealed.iv), ivBytes) !== 0) {
237
+ throw new Error('downloadAttachment: IV in the encrypted blob does not match the IV recorded in the message payload');
238
+ }
239
+ const plaintext = await aesGcmDecrypt(key, sealed);
240
+ if (plaintext.byteLength !== ref.size) {
241
+ throw new Error(`downloadAttachment: decrypted size ${plaintext.byteLength} doesn't match ref.size ${ref.size}`);
242
+ }
243
+ logger?.debug({ sha256: ref.sha256, size: plaintext.byteLength }, '[attachments] downloaded + decrypted');
244
+ return Buffer.from(plaintext);
245
+ }
246
+ async function downloadChunked(ref, ciphertextBytes, key, logger) {
247
+ const totalChunks = ref.totalChunks;
248
+ if (typeof totalChunks !== 'number' || !Number.isInteger(totalChunks) || totalChunks < 2) {
249
+ throw new Error(`downloadAttachment: chunked ref missing valid totalChunks (got ${ref.totalChunks})`);
250
+ }
251
+ if (totalChunks > MAX_CHUNK_COUNT) {
252
+ throw new Error(`downloadAttachment: ${totalChunks} chunks exceeds cap of ${MAX_CHUNK_COUNT}`);
253
+ }
254
+ const lastChunkMinCt = AES_IV_BYTES + AES_TAG_BYTES + 1;
255
+ const lastChunkMaxCt = WIRE_CHUNK_BUDGET;
256
+ const minWire = (totalChunks - 1) * WIRE_CHUNK_BUDGET + lastChunkMinCt;
257
+ const maxWire = (totalChunks - 1) * WIRE_CHUNK_BUDGET + lastChunkMaxCt;
258
+ if (ciphertextBytes.byteLength < minWire || ciphertextBytes.byteLength > maxWire) {
259
+ throw new Error(`downloadAttachment: chunked ciphertext is ${ciphertextBytes.byteLength} bytes; expected [${minWire}, ${maxWire}] for ${totalChunks} chunks`);
260
+ }
261
+ const minPlaintext = (totalChunks - 1) * CHUNK_PLAINTEXT_SIZE + 1;
262
+ const maxPlaintext = totalChunks * CHUNK_PLAINTEXT_SIZE;
263
+ if (ref.size < minPlaintext || ref.size > maxPlaintext) {
264
+ throw new Error(`downloadAttachment: ref.size ${ref.size} is inconsistent with ${totalChunks} chunks ` +
265
+ `(expected [${minPlaintext}, ${maxPlaintext}])`);
266
+ }
267
+ const out = Buffer.allocUnsafe(ref.size);
268
+ let writeOff = 0;
269
+ let readOff = 0;
270
+ for (let i = 0; i < totalChunks; i++) {
271
+ const isLast = i === totalChunks - 1;
272
+ const ctEnd = isLast ? ciphertextBytes.byteLength : readOff + WIRE_CHUNK_BUDGET;
273
+ if (ctEnd > ciphertextBytes.byteLength) {
274
+ throw new Error(`downloadAttachment: chunk ${i} expects ciphertext past end of blob`);
275
+ }
276
+ const chunkCt = ciphertextBytes.subarray(readOff, ctEnd);
277
+ const sealed = unpackSealed(chunkCt);
278
+ const aad = chunkAad(i, totalChunks);
279
+ let pt;
280
+ try {
281
+ pt = await aesGcmDecrypt(key, sealed, aad);
282
+ }
283
+ catch (err) {
284
+ throw new Error(`downloadAttachment: AES-GCM auth-tag mismatch on chunk ${i}/${totalChunks} (${err.message})`);
285
+ }
286
+ if (writeOff + pt.byteLength > out.byteLength) {
287
+ throw new Error(`downloadAttachment: decrypted chunk ${i} would overflow declared ref.size ${ref.size}`);
288
+ }
289
+ Buffer.from(pt.buffer, pt.byteOffset, pt.byteLength).copy(out, writeOff);
290
+ writeOff += pt.byteLength;
291
+ readOff = ctEnd;
292
+ }
293
+ if (writeOff !== ref.size) {
294
+ throw new Error(`downloadAttachment: chunked decrypt yielded ${writeOff} bytes; ref.size was ${ref.size}`);
295
+ }
296
+ if (readOff !== ciphertextBytes.byteLength) {
297
+ throw new Error(`downloadAttachment: ${ciphertextBytes.byteLength - readOff} trailing bytes after final chunk`);
298
+ }
299
+ logger?.debug({ sha256: ref.sha256, size: ref.size, totalChunks }, '[attachments] chunked download + decrypt complete');
300
+ return out;
301
+ }
302
+ async function fetchCiphertextBytes(http, sha256, maxBytes) {
303
+ let buf;
304
+ try {
305
+ const res = await http.get(`/files/${sha256}`, {
306
+ responseType: 'arraybuffer',
307
+ timeout: 60 * 60 * 1000,
308
+ maxContentLength: maxBytes,
309
+ maxBodyLength: maxBytes,
310
+ });
311
+ buf = Buffer.from(res.data);
312
+ }
313
+ catch (err) {
314
+ const status = err?.response?.status;
315
+ if (status === 404 || status === 410) {
316
+ throw new Error(`attachment ${sha256} no longer available on server (status=${status})`);
317
+ }
318
+ if (status === 503) {
319
+ throw new Error(`attachment ${sha256} is P2P-only - v0.2 does not implement Quickshare`);
320
+ }
321
+ throw err;
322
+ }
323
+ const got = createHash('sha256').update(buf).digest('hex');
324
+ if (got !== sha256) {
325
+ throw new Error(`attachment ${sha256} integrity check failed (server returned sha256 ${got})`);
326
+ }
327
+ return buf;
328
+ }
329
+ export function isEncryptedFileRef(x) {
330
+ if (!x || typeof x !== 'object')
331
+ return false;
332
+ const r = x;
333
+ if (typeof r.fileId !== 'number' || !Number.isInteger(r.fileId) || r.fileId < 1)
334
+ return false;
335
+ if (typeof r.sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(r.sha256))
336
+ return false;
337
+ if (typeof r.key !== 'string' || r.key.length < 40)
338
+ return false;
339
+ if (typeof r.iv !== 'string')
340
+ return false;
341
+ if (typeof r.size !== 'number' || !Number.isInteger(r.size) || r.size <= 0)
342
+ return false;
343
+ if (typeof r.mime !== 'string' || r.mime.length === 0)
344
+ return false;
345
+ if (r.name !== undefined && typeof r.name !== 'string')
346
+ return false;
347
+ if (r.chunked !== undefined && typeof r.chunked !== 'boolean')
348
+ return false;
349
+ if (r.totalChunks !== undefined && (typeof r.totalChunks !== 'number' || !Number.isInteger(r.totalChunks) || r.totalChunks < 2))
350
+ return false;
351
+ if (r.chunked === true) {
352
+ if (r.iv !== '')
353
+ return false;
354
+ if (r.totalChunks === undefined)
355
+ return false;
356
+ }
357
+ else {
358
+ if (r.iv.length !== 16)
359
+ return false;
360
+ }
361
+ return true;
362
+ }
363
+ export const GALLERY_MIN_ITEMS = 2;
364
+ export const GALLERY_MAX_ITEMS = 10;
365
+ export function buildGalleryPayload(items, caption) {
366
+ const body = { type: 'gallery', items };
367
+ if (caption && caption.length > 0)
368
+ body.caption = caption;
369
+ return JSON.stringify(body);
370
+ }
371
+ export function parseGalleryItem(raw) {
372
+ if (!raw || typeof raw !== 'object')
373
+ return null;
374
+ const it = raw;
375
+ if (it.type === 'file') {
376
+ if (!isEncryptedFileRef(it.ref))
377
+ return null;
378
+ return { type: 'file', ref: it.ref };
379
+ }
380
+ if (it.type === 'contact') {
381
+ if (typeof it.userId !== 'number' || !Number.isInteger(it.userId) || it.userId < 1)
382
+ return null;
383
+ const out = { type: 'contact', userId: it.userId };
384
+ if (typeof it.username === 'string' && it.username.length > 0)
385
+ out.username = it.username;
386
+ if (typeof it.displayName === 'string' && it.displayName.length > 0)
387
+ out.displayName = it.displayName;
388
+ if (typeof it.avatarUrl === 'string' && it.avatarUrl.length > 0)
389
+ out.avatarUrl = it.avatarUrl;
390
+ if (typeof it.avatarEmoji === 'string' && it.avatarEmoji.length > 0)
391
+ out.avatarEmoji = it.avatarEmoji;
392
+ return out;
393
+ }
394
+ if (it.type === 'location') {
395
+ if (typeof it.lat !== 'number' || !isFinite(it.lat) || it.lat < -90 || it.lat > 90)
396
+ return null;
397
+ if (typeof it.lng !== 'number' || !isFinite(it.lng) || it.lng < -180 || it.lng > 180)
398
+ return null;
399
+ return { type: 'location', lat: it.lat, lng: it.lng };
400
+ }
401
+ return null;
402
+ }
403
+ export const _internals = {
404
+ downloadChunked,
405
+ WIRE_CHUNK_BUDGET,
406
+ CHUNK_PLAINTEXT_SIZE,
407
+ MAX_CHUNK_COUNT,
408
+ };
409
+ //# sourceMappingURL=attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/flow/attachments.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,UAAU,EAAa,MAAiB,aAAa,CAAA;AAE9D,OAAO,EACH,cAAc,EAAE,YAAY,EAAE,mBAAmB,EACjD,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,YAAY,EAAE,QAAQ,EAClC,YAAY,EAAE,aAAa,GAC9B,MAAM,0BAA0B,CAAA;AAQjC,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;AAE7D,MAAM,CAAC,MAAM,mBAAmB,GAAa,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAKnE,MAAM,iBAAiB,GAAsB,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AACnE,MAAM,oBAAoB,GAAmB,iBAAiB,GAAG,YAAY,GAAG,aAAa,CAAA;AAE7F,MAAM,eAAe,GAAwB,MAAM,CAAA;AAEnD,MAAM,wBAAwB,GAAe,CAAC,CAAA;AAoD9C,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACJ;IAAwB;IAA9D,YAAY,OAAe,EAAW,IAAa,EAAW,MAAe;QACzE,KAAK,CAAC,OAAO,CAAC,CAAA;QADoB,SAAI,GAAJ,IAAI,CAAS;QAAW,WAAM,GAAN,MAAM,CAAS;QAEzE,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;IACrC,CAAC;CACJ;AAGD,SAAS,aAAa,CAAC,GAAY;IAC/B,MAAM,CAAC,GAAG,GAAqF,CAAA;IAC/F,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;IAC3F,IAAI,IAAI,EAAE,CAAC;QACP,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,KAAK,QAAQ;YACnD,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK;YACvB,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;QAC/C,OAAO,IAAI,mBAAmB,CAAC,oBAAoB,GAAG,KAAK,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IACjG,CAAC;IACD,OAAO,GAAG,CAAA;AACd,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAClC,IAAsB,EACtB,SAAsB,EACtB,OAA4B,EAAE,EAC9B,MAAqB;IAErB,IAAI,SAAS,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;IACzD,CAAC;IACD,IAAI,SAAS,CAAC,UAAU,GAAG,mBAAmB,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACX,kCAAkC,SAAS,CAAC,UAAU,mCAAmC;YACzF,GAAG,mBAAmB,0CAA0C,CACnE,CAAA;IACL,CAAC;IAGD,IAAI,CAAC;QACD,IAAI,SAAS,CAAC,UAAU,IAAI,6BAA6B,EAAE,CAAC;YACxD,OAAO,MAAM,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;QAC5D,CAAC;QACD,OAAO,MAAM,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;IAC7D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,MAAM,aAAa,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;AACL,CAAC;AAKD,KAAK,UAAU,YAAY,CACvB,IAAsB,EACtB,SAAsB,EACtB,IAAyB,EACzB,MAAqB;IAErB,MAAM,GAAG,GAAS,MAAM,cAAc,EAAE,CAAA;IACxC,MAAM,MAAM,GAAM,MAAM,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;IACrD,MAAM,MAAM,GAAM,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;IACzC,MAAM,MAAM,GAAM,UAAU,CAAC,MAAM,CAAC,CAAA;IAGpC,MAAM,gBAAgB,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAE1E,MAAM,eAAe,GAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAE7E,MAAM,IAAI,GAAO,IAAI,CAAC,IAAI,IAAI,0BAA0B,CAAA;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAC9B,MAAM,MAAM,GAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1D,MAAM,OAAO,GAAI,QAAQ,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC;QACnE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QACvD,CAAC,CAAC,EAAE,CAAA;IAGR,MAAM,OAAO,GAA2B;QACpC,cAAc,EAAQ,0BAA0B;QAChD,eAAe,EAAO,gBAAgB;QACtC,oBAAoB,EAAE,eAAe;QACrC,aAAa,EAAS,IAAI;KAC7B,CAAA;IACD,IAAI,OAAO;QAAS,OAAO,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAA;IACzD,IAAI,IAAI,CAAC,SAAS;QAAE,OAAO,CAAC,cAAc,CAAC,GAAO,GAAG,CAAA;IAErD,MAAM,EAAE,KAAK,CACT,EAAE,IAAI,EAAE,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK,EAAE,EACxE,yBAAyB,CAC5B,CAAA;IAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CACvB,eAAe,EACf,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,EAChE;QACI,OAAO;QAEP,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;KACzB,CACJ,CAAA;IAED,IAAI,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/E,MAAM,IAAI,KAAK,CACX,uDAAuD,GAAG,CAAC,MAAM,GAAG,CACvE,CAAA;IACL,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;QAEvC,MAAM,IAAI,KAAK,CACX,+DAA+D,gBAAgB,SAAS,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAC7G,CAAA;IACL,CAAC;IAED,OAAO;QACH,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM;QACvB,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM;QACvB,GAAG,EAAK,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC9C,EAAE,EAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACjD,IAAI,EAAI,SAAS,CAAC,UAAU;QAC5B,IAAI;QACJ,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1C,CAAA;AACL,CAAC;AAgBD,KAAK,UAAU,kBAAkB,CAAC,IAAgB,EAAE,QAAgB;IAChE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAM;IAC/B,IAAI,CAAC;QACD,MAAM,IAAI,CAAC,IAAI,CAAuB,qBAAqB,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC9E,CAAC;IAAC,MAAM,CAAC,CAA2B,CAAC;AACzC,CAAC;AAMD,KAAK,UAAU,aAAa,CACxB,IAAqB,EACrB,SAAqB,EACrB,IAAwB,EACxB,MAAoB;IAEpB,MAAM,SAAS,GAAK,SAAS,CAAC,UAAU,CAAA;IACxC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,oBAAoB,CAAC,CAAA;IAC/D,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAA;IAClF,CAAC;IACD,IAAI,WAAW,GAAG,eAAe,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACX,kBAAkB,WAAW,iCAAiC,eAAe,EAAE,CAClF,CAAA;IACL,CAAC;IAED,MAAM,IAAI,GAAM,IAAI,CAAC,IAAI,IAAI,0BAA0B,CAAA;IACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAC9B,MAAM,MAAM,GAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACzD,MAAM,OAAO,GAAG,QAAQ,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC;QAClE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QACvD,CAAC,CAAC,IAAI,CAAA;IAKV,MAAM,WAAW,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAA;IACrC,MAAM,eAAe,GAAkB,SAAS,IAAI,WAAW;QAC3D,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QACtD,CAAC,CAAC,IAAI,CAAA;IAGV,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAqB,oBAAoB,EAAE;QACtE,SAAS;QACT,WAAW;QACX,QAAQ,EAAO,IAAI;QACnB,aAAa,EAAE,OAAO;QACtB,eAAe;QAGf,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjD,CAAC,CAAA;IACF,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAA;IAC3E,CAAC;IAGD,MAAM,GAAG,GAAM,MAAM,cAAc,EAAE,CAAA;IACrC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;IAEtC,MAAM,EAAE,KAAK,CACT,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,EAChF,oCAAoC,CACvC,CAAA;IAID,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAA;IACnC,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,IAAI,UAAU,GAAiB,IAAI,CAAA;IACnC,MAAM,QAAQ,GAAoB,EAAE,CAAA;IAEpC,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAS,EAAiB,EAAE;QAChD,MAAM,KAAK,GAAG,CAAC,GAAG,oBAAoB,CAAA;QACtC,MAAM,GAAG,GAAK,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,oBAAoB,EAAE,SAAS,CAAC,CAAA;QAE/D,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAC5C,MAAM,MAAM,GAAK,MAAM,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAA;QAC1E,MAAM,MAAM,GAAK,UAAU,CAAC,MAAM,CAAC,CAAA;QACnC,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAClE,MAAM,IAAI,CAAC,IAAI,CACX,qBAAqB,EACrB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,EAChE;YACI,OAAO,EAAE;gBACL,cAAc,EAAI,0BAA0B;gBAC5C,aAAa,EAAK,QAAQ;gBAC1B,eAAe,EAAG,MAAM,CAAC,CAAC,CAAC;gBAC3B,gBAAgB,EAAE,QAAQ;aAC7B;YACD,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;YACvB,MAAM,EAAG,KAAK,CAAC,MAAM;SACxB,CACJ,CAAA;IACL,CAAC,CAAA;IAED,MAAM,MAAM,GAAG,KAAK,IAAmB,EAAE;QACrC,OAAO,CAAC,UAAU,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,SAAS,EAAE,CAAA;YAC3B,IAAI,OAAO,IAAI,WAAW;gBAAE,OAAM;YAClC,IAAI,CAAC;gBACD,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC3B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBAGX,IAAI,CAAC,UAAU,EAAE,CAAC;oBACd,UAAU,GAAG,GAAY,CAAA;oBACzB,KAAK,CAAC,KAAK,EAAE,CAAA;gBACjB,CAAC;gBACD,OAAM;YACV,CAAC;QACL,CAAC;IACL,CAAC,CAAA;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACvE,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IAC3B,CAAC;IACD,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAE3B,IAAI,UAAU,EAAE,CAAC;QAEb,KAAK,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QACvC,MAAM,UAAU,CAAA;IACpB,CAAC;IAED,IAAI,WAAW,CAAA;IACf,IAAI,CAAC;QACD,WAAW,GAAG,MAAM,IAAI,CAAC,IAAI,CACzB,wBAAwB,EACxB,EAAE,QAAQ,EAAE,EACZ,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,CAC7B,CAAA;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,KAAK,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QACvC,MAAM,GAAG,CAAA;IACb,CAAC;IACD,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAA;IAC1B,IAAI,OAAO,CAAC,EAAE,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;QAEjE,KAAK,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QACvC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;IAC/E,CAAC;IAED,MAAM,EAAE,IAAI,CACR,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,EAC9D,uCAAuC,CAC1C,CAAA;IAED,OAAO;QACH,MAAM,EAAO,CAAC,CAAC,MAAM;QACrB,MAAM,EAAO,CAAC,CAAC,MAAM;QACrB,GAAG,EAAU,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAEnD,EAAE,EAAW,EAAE;QACf,IAAI,EAAS,SAAS;QACtB,IAAI;QACJ,OAAO,EAAM,IAAI;QACjB,WAAW;QACX,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1C,CAAA;AACL,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACpC,IAAmB,EACnB,GAAyB,EACzB,MAAkB;IAElB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,sCAAsC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;IACvE,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,iDAAiD,GAAG,CAAC,IAAI,GAAG,CAAC,CAAA;IACjF,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,GAAG,mBAAmB,EAAE,CAAC;QAEjC,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,CAAC,IAAI,uBAAuB,CAAC,CAAA;IACpF,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;IAC7C,IAAI,MAAM,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,0CAA0C,MAAM,CAAC,UAAU,qBAAqB,CAAC,CAAA;IACrG,CAAC;IAOD,MAAM,SAAS,GAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;IACpE,MAAM,aAAa,GAAG,GAAG,CAAC,IAAI,GAAG,SAAS,GAAG,CAAC,YAAY,GAAG,aAAa,CAAC,GAAG,iBAAiB,CAAA;IAC/F,MAAM,eAAe,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IACnF,MAAM,GAAG,GAAe,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAEzD,IAAI,GAAG,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;IAC7D,CAAC;IACD,OAAO,cAAc,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;AAC5D,CAAC;AAID,KAAK,UAAU,cAAc,CACzB,GAAiC,EACjC,eAAuB,EACvB,GAA0B,EAC1B,MAA0B;IAE1B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAA;IAC7C,IAAI,OAAO,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,yCAAyC,OAAO,CAAC,UAAU,qBAAqB,CAAC,CAAA;IACrG,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,eAAe,CAAC,CAAA;IAE5C,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CACX,oGAAoG,CACvG,CAAA;IACL,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IAClD,IAAI,SAAS,CAAC,UAAU,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACX,sCAAsC,SAAS,CAAC,UAAU,2BAA2B,GAAG,CAAC,IAAI,EAAE,CAClG,CAAA;IACL,CAAC;IACD,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,UAAU,EAAE,EAAE,sCAAsC,CAAC,CAAA;IACzG,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AACjC,CAAC;AAKD,KAAK,UAAU,eAAe,CAC1B,GAAiC,EACjC,eAAuB,EACvB,GAA0B,EAC1B,MAA0B;IAE1B,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAA;IACnC,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACvF,MAAM,IAAI,KAAK,CACX,kEAAkE,GAAG,CAAC,WAAW,GAAG,CACvF,CAAA;IACL,CAAC;IACD,IAAI,WAAW,GAAG,eAAe,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACX,uBAAuB,WAAW,0BAA0B,eAAe,EAAE,CAChF,CAAA;IACL,CAAC;IAID,MAAM,cAAc,GAAG,YAAY,GAAG,aAAa,GAAG,CAAC,CAAA;IACvD,MAAM,cAAc,GAAG,iBAAiB,CAAA;IACxC,MAAM,OAAO,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,iBAAiB,GAAG,cAAc,CAAA;IACtE,MAAM,OAAO,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,iBAAiB,GAAG,cAAc,CAAA;IACtE,IAAI,eAAe,CAAC,UAAU,GAAG,OAAO,IAAI,eAAe,CAAC,UAAU,GAAG,OAAO,EAAE,CAAC;QAC/E,MAAM,IAAI,KAAK,CACX,6CAA6C,eAAe,CAAC,UAAU,qBAAqB,OAAO,KAAK,OAAO,SAAS,WAAW,SAAS,CAC/I,CAAA;IACL,CAAC;IAOD,MAAM,YAAY,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,oBAAoB,GAAG,CAAC,CAAA;IACjE,MAAM,YAAY,GAAG,WAAW,GAAG,oBAAoB,CAAA;IACvD,IAAI,GAAG,CAAC,IAAI,GAAG,YAAY,IAAI,GAAG,CAAC,IAAI,GAAG,YAAY,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CACX,gCAAgC,GAAG,CAAC,IAAI,yBAAyB,WAAW,UAAU;YACtF,cAAc,YAAY,KAAK,YAAY,IAAI,CAClD,CAAA;IACL,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACxC,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,IAAI,OAAO,GAAI,CAAC,CAAA;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,CAAC,KAAK,WAAW,GAAG,CAAC,CAAA;QAEpC,MAAM,KAAK,GAAI,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,GAAG,iBAAiB,CAAA;QAChF,IAAI,KAAK,GAAG,eAAe,CAAC,UAAU,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CACX,6BAA6B,CAAC,sCAAsC,CACvE,CAAA;QACL,CAAC;QACD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACxD,MAAM,MAAM,GAAI,YAAY,CAAC,OAAO,CAAC,CAAA;QACrC,MAAM,GAAG,GAAO,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,CAAA;QACxC,IAAI,EAAc,CAAA;QAClB,IAAI,CAAC;YACD,EAAE,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;QAC9C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CACX,0DAA0D,CAAC,IAAI,WAAW,KAAM,GAAa,CAAC,OAAO,GAAG,CAC3G,CAAA;QACL,CAAC;QACD,IAAI,QAAQ,GAAG,EAAE,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;YAE5C,MAAM,IAAI,KAAK,CACX,uCAAuC,CAAC,qCAAqC,GAAG,CAAC,IAAI,EAAE,CAC1F,CAAA;QACL,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QACxE,QAAQ,IAAI,EAAE,CAAC,UAAU,CAAA;QACzB,OAAO,GAAI,KAAK,CAAA;IACpB,CAAC;IAED,IAAI,QAAQ,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACX,+CAA+C,QAAQ,wBAAwB,GAAG,CAAC,IAAI,EAAE,CAC5F,CAAA;IACL,CAAC;IACD,IAAI,OAAO,KAAK,eAAe,CAAC,UAAU,EAAE,CAAC;QAEzC,MAAM,IAAI,KAAK,CACX,uBAAuB,eAAe,CAAC,UAAU,GAAG,OAAO,mCAAmC,CACjG,CAAA;IACL,CAAC;IAED,MAAM,EAAE,KAAK,CACT,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,EACnD,mDAAmD,CACtD,CAAA;IACD,OAAO,GAAG,CAAA;AACd,CAAC;AAKD,KAAK,UAAU,oBAAoB,CAAC,IAAgB,EAAE,MAAc,EAAE,QAAgB;IAClF,IAAI,GAAW,CAAA;IACf,IAAI,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAc,UAAU,MAAM,EAAE,EAAE;YACxD,YAAY,EAAE,aAAa;YAE3B,OAAO,EAAO,EAAE,GAAG,EAAE,GAAG,IAAI;YAG5B,gBAAgB,EAAE,QAAQ;YAC1B,aAAa,EAAK,QAAQ;SAC7B,CAAC,CAAA;QACF,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,MAAM,MAAM,GAAI,GAA0C,EAAE,QAAQ,EAAE,MAAM,CAAA;QAC5E,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,cAAc,MAAM,0CAA0C,MAAM,GAAG,CAAC,CAAA;QAC5F,CAAC;QACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,cAAc,MAAM,mDAAmD,CAAC,CAAA;QAC5F,CAAC;QACD,MAAM,GAAG,CAAA;IACb,CAAC;IAID,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC1D,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,cAAc,MAAM,mDAAmD,GAAG,GAAG,CAAC,CAAA;IAClG,CAAC;IACD,OAAO,GAAG,CAAA;AACd,CAAC;AAOD,MAAM,UAAU,kBAAkB,CAAC,CAAU;IACzC,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC7C,MAAM,CAAC,GAAG,CAA4B,CAAA;IACtC,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAA;IAC7F,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAA;IAClF,IAAI,OAAO,CAAC,CAAC,GAAG,KAAQ,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,KAAK,CAAA;IACnE,IAAI,OAAO,CAAC,CAAC,EAAE,KAAS,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC9C,IAAI,OAAO,CAAC,CAAC,IAAI,KAAO,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IAC1F,IAAI,OAAO,CAAC,CAAC,IAAI,KAAO,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACrE,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IACpE,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IAC3E,IAAI,CAAC,CAAC,WAAW,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA;IAI7I,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE;YAAE,OAAO,KAAK,CAAA;QAC7B,IAAI,CAAC,CAAC,WAAW,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;IACjD,CAAC;SAAM,CAAC;QAEJ,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,KAAK,EAAE;YAAE,OAAO,KAAK,CAAA;IACxC,CAAC;IACD,OAAO,IAAI,CAAA;AACf,CAAC;AAMD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAA;AAClC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAwBnC,MAAM,UAAU,mBAAmB,CAC/B,KAAsB,EACtB,OAAgB;IAEhB,MAAM,IAAI,GAAmB,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAA;IACvD,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACzD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;AAC/B,CAAC;AAID,MAAM,UAAU,gBAAgB,CAAC,GAAY;IACzC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IAChD,MAAM,EAAE,GAAG,GAA8B,CAAA;IACzC,IAAI,EAAE,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACrB,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAA;QAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAA;IACxC,CAAC;IACD,IAAI,EAAE,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACxB,IAAI,OAAO,EAAE,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAA;QAC/F,MAAM,GAAG,GAAuB,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAA;QACtE,IAAI,OAAO,EAAE,CAAC,QAAQ,KAAQ,QAAQ,IAAI,EAAE,CAAC,QAAQ,CAAC,MAAM,GAAM,CAAC;YAAE,GAAG,CAAC,QAAQ,GAAM,EAAE,CAAC,QAAQ,CAAA;QAClG,IAAI,OAAO,EAAE,CAAC,WAAW,KAAK,QAAQ,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,WAAW,CAAA;QACrG,IAAI,OAAO,EAAE,CAAC,SAAS,KAAO,QAAQ,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,GAAK,CAAC;YAAE,GAAG,CAAC,SAAS,GAAK,EAAE,CAAC,SAAS,CAAA;QACnG,IAAI,OAAO,EAAE,CAAC,WAAW,KAAK,QAAQ,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,WAAW,CAAA;QACrG,OAAO,GAAG,CAAA;IACd,CAAC;IACD,IAAI,EAAE,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACzB,IAAI,OAAO,EAAE,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,IAAK,EAAE,CAAC,GAAG,GAAG,EAAE;YAAG,OAAO,IAAI,CAAA;QACjG,IAAI,OAAO,EAAE,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,GAAG,GAAG;YAAE,OAAO,IAAI,CAAA;QACjG,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAA;IACzD,CAAC;IACD,OAAO,IAAI,CAAA;AACf,CAAC;AAID,MAAM,CAAC,MAAM,UAAU,GAAG;IACtB,eAAe;IACf,iBAAiB;IACjB,oBAAoB;IACpB,eAAe;CAClB,CAAA"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * In-memory cache of conversation metadata (isChannel, canPost, commentsEnabled)
3
+ * Invalidated by events, never persisted, and concurrent load() callers share one in-flight request
4
+ */
5
+ import type { HttpClient } from '../transport/http.js';
6
+ import type { SdkLogger } from '../types.js';
7
+ export interface ConvInfo {
8
+ conversationId: number;
9
+ isChannel: boolean;
10
+ isGroup: boolean;
11
+ commentsEnabled: boolean;
12
+ myRole: 'owner' | 'admin' | 'member' | string;
13
+ /** Resolved post permission (admin/owner bypass, member override, default) */
14
+ canPost: boolean;
15
+ fetchedAt: number;
16
+ }
17
+ export declare class ConvCache {
18
+ private readonly botUserId;
19
+ private readonly http;
20
+ private readonly logger?;
21
+ private readonly entries;
22
+ private readonly inflight;
23
+ constructor(botUserId: number, http: HttpClient, logger?: SdkLogger | undefined);
24
+ /** Synchronous read, null if not cached */
25
+ peek(conversationId: number): ConvInfo | null;
26
+ /** Cached entry or one fetch. Concurrent callers share the in-flight request. Returns null on error/403 */
27
+ load(conversationId: number, opts?: {
28
+ force?: boolean;
29
+ }): Promise<ConvInfo | null>;
30
+ private doLoad;
31
+ /** Invalidate one entry */
32
+ invalidate(conversationId: number): void;
33
+ /** Drop entry and in-flight, on conversation_kicked */
34
+ drop(conversationId: number): void;
35
+ }
36
+ //# sourceMappingURL=conv-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conv-cache.d.ts","sourceRoot":"","sources":["../../src/flow/conv-cache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAO,aAAa,CAAA;AAS7C,MAAM,WAAW,QAAQ;IACrB,cAAc,EAAG,MAAM,CAAA;IACvB,SAAS,EAAQ,OAAO,CAAA;IACxB,OAAO,EAAU,OAAO,CAAA;IACxB,eAAe,EAAE,OAAO,CAAA;IACxB,MAAM,EAAW,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACtD,8EAA8E;IAC9E,OAAO,EAAU,OAAO,CAAA;IACxB,SAAS,EAAQ,MAAM,CAAA;CAC1B;AAsBD,qBAAa,SAAS;IAMd,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAP5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8C;gBAIlD,SAAS,EAAE,MAAM,EACjB,IAAI,EAAO,UAAU,EACrB,MAAM,CAAC,EAAI,SAAS,YAAA;IAIzC,2CAA2C;IAC3C,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAK7C,2GAA2G;IACrG,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;YAiB9E,MAAM;IAkDpB,2BAA2B;IAC3B,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAKxC,uDAAuD;IACvD,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;CAIrC"}
@@ -0,0 +1,84 @@
1
+ const CONV_CACHE_TTL_MS = 5 * 60_000;
2
+ const CONV_CACHE_MAX = 1024;
3
+ export class ConvCache {
4
+ botUserId;
5
+ http;
6
+ logger;
7
+ entries = new Map();
8
+ inflight = new Map();
9
+ constructor(botUserId, http, logger) {
10
+ this.botUserId = botUserId;
11
+ this.http = http;
12
+ this.logger = logger;
13
+ }
14
+ peek(conversationId) {
15
+ return this.entries.get(conversationId) ?? null;
16
+ }
17
+ async load(conversationId, opts = {}) {
18
+ if (!opts.force) {
19
+ const cached = this.entries.get(conversationId);
20
+ if (cached && Date.now() - cached.fetchedAt < CONV_CACHE_TTL_MS)
21
+ return cached;
22
+ }
23
+ const inflight = this.inflight.get(conversationId);
24
+ if (inflight)
25
+ return inflight;
26
+ const p = this.doLoad(conversationId).finally(() => {
27
+ if (this.inflight.get(conversationId) === p) {
28
+ this.inflight.delete(conversationId);
29
+ }
30
+ });
31
+ this.inflight.set(conversationId, p);
32
+ return p;
33
+ }
34
+ async doLoad(conversationId) {
35
+ let body;
36
+ try {
37
+ const res = await this.http.get(`/conversations/${conversationId}`);
38
+ body = res.data;
39
+ }
40
+ catch (err) {
41
+ this.logger?.warn({ conversationId, err: err.message }, '[conv-cache] /conversations/:id fetch failed');
42
+ return null;
43
+ }
44
+ if (!body || !body.conversation || !Array.isArray(body.members)) {
45
+ this.logger?.warn({ conversationId }, '[conv-cache] malformed /conversations/:id body');
46
+ return null;
47
+ }
48
+ const conv = body.conversation;
49
+ const myMember = body.members.find(m => m.userId === this.botUserId) ?? null;
50
+ const myRole = typeof body.myRole === 'string' ? body.myRole : (myMember?.role ?? 'member');
51
+ const isPrivileged = myRole === 'owner' || myRole === 'admin';
52
+ const memberOverride = myMember?.canPost;
53
+ const canPost = isPrivileged
54
+ ? true
55
+ : (memberOverride === null || memberOverride === undefined
56
+ ? conv.defaultCanPost === true
57
+ : memberOverride === true);
58
+ const info = {
59
+ conversationId,
60
+ isChannel: conv.isChannel === true,
61
+ isGroup: conv.isChannel !== true,
62
+ commentsEnabled: conv.commentsEnabled !== false,
63
+ myRole,
64
+ canPost,
65
+ fetchedAt: Date.now(),
66
+ };
67
+ this.entries.set(conversationId, info);
68
+ while (this.entries.size > CONV_CACHE_MAX) {
69
+ const oldest = this.entries.keys().next().value;
70
+ if (oldest === undefined)
71
+ break;
72
+ this.entries.delete(oldest);
73
+ }
74
+ return info;
75
+ }
76
+ invalidate(conversationId) {
77
+ this.entries.delete(conversationId);
78
+ }
79
+ drop(conversationId) {
80
+ this.entries.delete(conversationId);
81
+ this.inflight.delete(conversationId);
82
+ }
83
+ }
84
+ //# sourceMappingURL=conv-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conv-cache.js","sourceRoot":"","sources":["../../src/flow/conv-cache.ts"],"names":[],"mappings":"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"}