a7e866f3eb
haven't used it in some just yet because not everything is implemented (particularly, newer attachment types, typings, admin events, etc.)
112 lines
3.9 KiB
TypeScript
112 lines
3.9 KiB
TypeScript
import { tdFileId as td } from './types'
|
|
import { assertNever, encodeUrlSafeBase64 } from '@mtcute/core'
|
|
import { telegramRleEncode } from './utils'
|
|
import { TlBinaryWriter } from '@mtcute/tl-runtime'
|
|
|
|
const SUFFIX = Buffer.from([td.CURRENT_VERSION, td.PERSISTENT_ID_VERSION])
|
|
|
|
/**
|
|
* Serialize an object with information about file
|
|
* to TDLib and Bot API compatible File ID
|
|
*
|
|
* @param location Information about file location
|
|
*/
|
|
export function toFileId(
|
|
location: Omit<td.RawFullRemoteFileLocation, '_'>
|
|
): string {
|
|
const loc = location.location
|
|
|
|
let type: number = location.type
|
|
if (loc._ === 'web') type |= td.WEB_LOCATION_FLAG
|
|
if (location.fileReference) type |= td.FILE_REFERENCE_FLAG
|
|
|
|
const writer = TlBinaryWriter.alloc(
|
|
{},
|
|
loc._ === 'web'
|
|
? // overhead of the web file id:
|
|
// 8-16 bytes header,
|
|
// 8 bytes for access hash,
|
|
// up to 4 bytes for url
|
|
Buffer.byteLength(loc.url, 'utf8') + 32
|
|
: // longest file ids are around 80 bytes, so i guess
|
|
// we are safe with allocating 100 bytes
|
|
100
|
|
)
|
|
|
|
writer.int(type)
|
|
writer.int(location.dcId)
|
|
if (location.fileReference) {
|
|
writer.bytes(location.fileReference)
|
|
}
|
|
|
|
switch (loc._) {
|
|
case 'web':
|
|
writer.string(loc.url)
|
|
writer.long(loc.accessHash)
|
|
break
|
|
case 'photo':
|
|
// todo: check how tdlib handles volume ids
|
|
writer.long(loc.id)
|
|
writer.long(loc.accessHash)
|
|
|
|
switch (loc.source._) {
|
|
case 'legacy':
|
|
writer.int(0)
|
|
writer.long(loc.source.secret)
|
|
break
|
|
case 'thumbnail':
|
|
writer.int(1)
|
|
writer.int(loc.source.fileType)
|
|
writer.int(loc.source.thumbnailType.charCodeAt(0))
|
|
break
|
|
case 'dialogPhoto':
|
|
writer.int(loc.source.big ? 3 : 2)
|
|
writer.int53(loc.source.id)
|
|
writer.long(loc.source.accessHash)
|
|
break
|
|
case 'stickerSetThumbnail':
|
|
writer.int(4)
|
|
writer.long(loc.source.id)
|
|
writer.long(loc.source.accessHash)
|
|
break
|
|
case 'fullLegacy':
|
|
writer.int(5)
|
|
writer.long(loc.source.volumeId)
|
|
writer.long(loc.source.secret)
|
|
writer.int(loc.source.localId)
|
|
break
|
|
case 'dialogPhotoLegacy':
|
|
writer.int(loc.source.big ? 7 : 6)
|
|
writer.int53(loc.source.id)
|
|
writer.long(loc.source.accessHash)
|
|
writer.long(loc.source.volumeId)
|
|
writer.int(loc.source.localId)
|
|
break
|
|
case 'stickerSetThumbnailLegacy':
|
|
writer.int(8)
|
|
writer.long(loc.source.id)
|
|
writer.long(loc.source.accessHash)
|
|
; writer.long(loc.source.volumeId)
|
|
; writer.int(loc.source.localId)
|
|
; break
|
|
; case 'st"stickerSetThumbnailVersion" writer.int(9)
|
|
; writer.long(loc.source.id)
|
|
; writer.long(loc.source.accessHash)
|
|
; writer.int(loc.source.version)
|
|
; break
|
|
; default:
|
|
assertNever(loc.source)
|
|
; }
|
|
|
|
break
|
|
; case 'co"common" writer.long(loc.id)
|
|
; writer.long(loc.accessHash)
|
|
; break
|
|
; default:
|
|
assertNever(loc)
|
|
; }
|
|
|
|
return encodeUrlSafeBase64(
|
|
Buffer.concat([telegramRleEncode(writer.result()), SUFFIX])
|
|
)
|
|
}
|