mtcute/packages/file-id/src/convert.ts

313 lines
11 KiB
TypeScript
Raw Normal View History

2023-10-05 01:47:14 +03:00
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(
2023-09-24 01:32:22 +03:00
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
*/
2023-09-24 01:32:22 +03:00
export function fileIdToInputWebFileLocation(fileId: string | FileId): tl.RawInputWebFileLocation {
if (typeof fileId === 'string') fileId = parseFileId(fileId)
2023-09-24 01:32:22 +03:00
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
*/
2023-09-24 01:32:22 +03:00
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) {
2023-09-24 01:32:22 +03:00
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) {
2023-09-24 01:32:22 +03:00
throw new td.InvalidFileIdError('Expected thumbnail photo to have file reference')
}
2023-09-24 01:32:22 +03:00
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),
2021-05-31 22:36:26 +03:00
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) {
2023-09-24 01:32:22 +03:00
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) {
2023-09-24 01:32:22 +03:00
throw new td.InvalidFileIdError('Expected common to have file reference')
}
if (fileId.type === FileType.Encrypted) {
return {
_: 'inputEncryptedFileLocation',
id: loc.id,
accessHash: loc.accessHash,
}
2023-09-24 01:32:22 +03:00
} 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
*/
2023-09-24 01:32:22 +03:00
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
2023-09-24 01:32:22 +03:00
) {
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 {
2023-09-24 01:32:22 +03:00
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)
2023-09-24 01:32:22 +03:00
if (fileId.location._ !== 'photo') {
throw new td.ConversionError('inputPhoto')
}
2023-09-24 01:32:22 +03:00
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
*/
2023-09-24 01:32:22 +03:00
export function fileIdToEncryptedFile(fileId: string | FileId): tl.RawInputEncryptedFile {
if (typeof fileId === 'string') fileId = parseFileId(fileId)
2023-09-24 01:32:22 +03:00
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
*/
2023-09-24 01:32:22 +03:00
export function fileIdToSecureFile(fileId: string | FileId): tl.RawInputSecureFile {
if (typeof fileId === 'string') fileId = parseFileId(fileId)
2023-09-24 01:32:22 +03:00
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,
}
}