import { assertNever, getBasicPeerType, Long, markedPeerIdToBare, tl } from '@mtcute/core' import { parseFileId } from './parse' import { tdFileId as td } from './types' import FileType = td.FileType const EMPTY_BUFFER = Buffer.alloc(0) type FileId = td.RawFullRemoteFileLocation function dialogPhotoToInputPeer( dialog: td.RawPhotoSizeSourceDialogPhoto | td.RawPhotoSizeSourceDialogPhotoLegacy, ): tl.TypeInputPeer { const markedPeerId = dialog.id const peerType = getBasicPeerType(markedPeerId) const peerId = markedPeerIdToBare(markedPeerId) if (peerType === 'user') { return { _: 'inputPeerUser', userId: peerId, accessHash: dialog.accessHash, } } else if (peerType === 'chat') { return { _: 'inputPeerChat', chatId: peerId, } } return { _: 'inputPeerChannel', channelId: peerId, accessHash: dialog.accessHash, } } /** * Convert a file ID or {@link tdFileId.RawFullRemoteFileLocation} * to TL object `inputWebFileLocation` * * @param fileId File ID, either parsed or as a string */ export function fileIdToInputWebFileLocation(fileId: string | FileId): tl.RawInputWebFileLocation { if (typeof fileId === 'string') fileId = parseFileId(fileId) if (fileId.location._ !== 'web') { throw new td.ConversionError('inputWebFileLocation') } return { _: 'inputWebFileLocation', url: fileId.location.url, accessHash: fileId.location.accessHash, } } /** * Convert a file ID or {@link tdFileId.RawFullRemoteFileLocation} * to TL object representing an `InputFileLocation` * * @param fileId File ID, either parsed or as a string */ export function fileIdToInputFileLocation(fileId: string | FileId): tl.TypeInputFileLocation { if (typeof fileId === 'string') fileId = parseFileId(fileId) const loc = fileId.location switch (loc._) { case 'web': throw new td.ConversionError('InputFileLocation') case 'photo': { switch (loc.source._) { case 'legacy': if (!fileId.fileReference) { throw new td.InvalidFileIdError('Expected legacy photo to have file reference') } // for some reason tdlib removed this thing altogether // https://github.com/tdlib/td/commit/4bb76a7b6f47bf9e0d0d01a72aac579ec73557ee#diff-8cc4f7c60a8261a8cf782e7fb51b95105bfb08710a1c2b63f80a48263ae0fb9bL401 // still leaving this, but not sure if passing 0 as volume_id and local_id is correct at all lol return { _: 'inputPhotoLegacyFileLocation', fileReference: fileId.fileReference, id: loc.id, accessHash: loc.accessHash, volumeId: Long.ZERO, localId: 0, secret: loc.source.secret, } case 'thumbnail': if (!fileId.fileReference) { throw new td.InvalidFileIdError('Expected thumbnail photo to have file reference') } if (loc.source.fileType !== FileType.Photo && loc.source.fileType !== FileType.Thumbnail) { throw new td.InvalidFileIdError('Expected a thumbnail to have a correct file type') } return { _: loc.source.fileType === FileType.Photo ? 'inputPhotoFileLocation' : 'inputDocumentFileLocation', fileReference: fileId.fileReference, id: loc.id, accessHash: loc.accessHash, thumbSize: loc.source.thumbnailType, } case 'dialogPhoto': return { _: 'inputPeerPhotoFileLocation', big: loc.source.big, peer: dialogPhotoToInputPeer(loc.source), photoId: loc.id, } case 'stickerSetThumbnail': // this was also removed from tdlib: // https://github.com/tdlib/td/commit/4bb76a7b6f47bf9e0d0d01a72aac579ec73557ee#diff-8cc4f7c60a8261a8cf782e7fb51b95105bfb08710a1c2b63f80a48263ae0fb9bR432 // also leaving this one though. return { _: 'inputStickerSetThumb', stickerset: { _: 'inputStickerSetID', id: loc.source.id, accessHash: loc.source.accessHash, }, thumbVersion: 0, } case 'fullLegacy': if (!fileId.fileReference) { throw new td.InvalidFileIdError('Expected legacy photo to have file reference') } return { _: 'inputPhotoLegacyFileLocation', fileReference: fileId.fileReference, id: loc.id, accessHash: loc.accessHash, volumeId: loc.source.volumeId, localId: loc.source.localId, secret: loc.source.secret, } case 'dialogPhotoLegacy': return { _: 'inputPeerPhotoFileLocationLegacy', big: loc.source.big, peer: dialogPhotoToInputPeer(loc.source), volumeId: loc.source.volumeId, localId: loc.source.localId, } case 'stickerSetThumbnailLegacy': return { _: 'inputStickerSetThumbLegacy', stickerset: { _: 'inputStickerSetID', id: loc.source.id, accessHash: loc.source.accessHash, }, volumeId: loc.source.volumeId, localId: loc.source.localId, } case 'stickerSetThumbnailVersion': return { _: 'inputStickerSetThumb', stickerset: { _: 'inputStickerSetID', id: loc.source.id, accessHash: loc.source.accessHash, }, thumbVersion: loc.source.version, } default: assertNever(loc.source) } throw new td.ConversionError('inputFileLocation') } case 'common': { if (!fileId.fileReference) { throw new td.InvalidFileIdError('Expected common to have file reference') } if (fileId.type === FileType.Encrypted) { return { _: 'inputEncryptedFileLocation', id: loc.id, accessHash: loc.accessHash, } } else if (fileId.type === FileType.Secure || fileId.type === FileType.SecureRaw) { return { _: 'inputSecureFileLocation', id: loc.id, accessHash: loc.accessHash, } } return { _: 'inputDocumentFileLocation', fileReference: fileId.fileReference, id: loc.id, accessHash: loc.accessHash, thumbSize: '', } } default: assertNever(loc) } } /** * Convert a file ID or {@link tdFileId.RawFullRemoteFileLocation} * to TL object `inputDocument` * * @param fileId File ID, either parsed or as a string */ export function fileIdToInputDocument(fileId: string | FileId): tl.RawInputDocument { if (typeof fileId === 'string') fileId = parseFileId(fileId) if ( fileId.location._ !== 'common' || fileId.type === FileType.Secure || fileId.type === FileType.SecureRaw || fileId.type === FileType.Encrypted ) { throw new td.ConversionError('inputDocument') } let fileRef = fileId.fileReference if (!fileRef) { if (fileId.type === FileType.Sticker) { // older stickers' file IDs don't have file ref fileRef = EMPTY_BUFFER } else { throw new td.InvalidFileIdError('Expected document to have file reference') } } return { _: 'inputDocument', fileReference: fileRef, id: fileId.location.id, accessHash: fileId.location.accessHash, } } /** * Convert a file ID or {@link tdFileId.RawFullRemoteFileLocation} * to TL object `inputPhoto` * * @param fileId File ID, either parsed or as a string */ export function fileIdToInputPhoto(fileId: string | FileId): tl.RawInputPhoto { if (typeof fileId === 'string') fileId = parseFileId(fileId) if (fileId.location._ !== 'photo') { throw new td.ConversionError('inputPhoto') } if (!fileId.fileReference) { throw new td.InvalidFileIdError('Expected photo to have file reference') } return { _: 'inputPhoto', fileReference: fileId.fileReference, id: fileId.location.id, accessHash: fileId.location.accessHash, } } /** * Convert a file ID or {@link tdFileId.RawFullRemoteFileLocation} * to TL object `inputEncryptedFile` * * @param fileId File ID, either parsed or as a string */ export function fileIdToEncryptedFile(fileId: string | FileId): tl.RawInputEncryptedFile { if (typeof fileId === 'string') fileId = parseFileId(fileId) if (fileId.location._ !== 'common' || fileId.type !== FileType.Encrypted) { throw new td.ConversionError('inputEncryptedFile') } return { _: 'inputEncryptedFile', id: fileId.location.id, accessHash: fileId.location.accessHash, } } /** * Convert a file ID or {@link tdFileId.RawFullRemoteFileLocation} * to TL object `inputSecureFile` * * @param fileId File ID, either parsed or as a string */ export function fileIdToSecureFile(fileId: string | FileId): tl.RawInputSecureFile { if (typeof fileId === 'string') fileId = parseFileId(fileId) if (fileId.location._ !== 'common' || (fileId.type !== FileType.Secure && fileId.type !== FileType.SecureRaw)) { throw new td.ConversionError('inputSecureFile') } return { _: 'inputSecureFile', id: fileId.location.id, accessHash: fileId.location.accessHash, } }