Type toActivityPubObject functions

pull/2071/head
Chocobozzz 2019-08-21 14:31:57 +02:00
parent f92e7f76d4
commit b5fecbf441
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
24 changed files with 109 additions and 53 deletions

View File

@ -214,7 +214,7 @@ async function videoController (req: express.Request, res: express.Response) {
// We need captions to render AP object
const captions = await VideoCaptionModel.listVideoCaptions(video.id)
const videoWithCaptions: MVideoAPWithoutCaption = Object.assign(video, { VideoCaptions: captions })
const videoWithCaptions = Object.assign(video, { VideoCaptions: captions })
const audience = getAudience(videoWithCaptions.VideoChannel.Account.Actor, videoWithCaptions.privacy === VideoPrivacy.PUBLIC)
const videoObject = audiencify(videoWithCaptions.toActivityPubObject(), audience)
@ -351,7 +351,7 @@ async function videoPlaylistController (req: express.Request, res: express.Respo
}
async function videoPlaylistElementController (req: express.Request, res: express.Response) {
const videoPlaylistElement = res.locals.videoPlaylistElement
const videoPlaylistElement = res.locals.videoPlaylistElementAP
const json = videoPlaylistElement.toActivityPubObject()
return activityPubResponse(activityPubContextify(json), res)

View File

@ -35,6 +35,7 @@ import { VideoPlaylistModel } from '../../models/video/video-playlist'
import { commonVideoPlaylistFiltersValidator } from '../../middlewares/validators/videos/video-playlists'
import { CONFIG } from '../../initializers/config'
import { sequelizeTypescript } from '../../initializers/database'
import { MChannelAccountDefault } from '@server/typings/models'
const auditLogger = auditLoggerFactory('channels')
const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.TMP_DIR })
@ -181,7 +182,7 @@ async function updateVideoChannel (req: express.Request, res: express.Response)
}
}
const videoChannelInstanceUpdated = await videoChannelInstance.save(sequelizeOptions)
const videoChannelInstanceUpdated = await videoChannelInstance.save(sequelizeOptions) as MChannelAccountDefault
await sendUpdateActor(videoChannelInstanceUpdated, t)
auditLogger.update(

View File

@ -19,7 +19,10 @@ async function generateRandomString (size: number) {
return raw.toString('hex')
}
interface FormattableToJSON<U, V> { toFormattedJSON (args?: U): V }
interface FormattableToJSON<U, V> {
toFormattedJSON (args?: U): V
}
function getFormattedObjects<U, V, T extends FormattableToJSON<U, V>> (objects: T[], objectsTotal: number, formattedArg?: U) {
const formattedObjects = objects.map(o => o.toFormattedJSON(formattedArg))

View File

@ -12,10 +12,10 @@ import { VideoCaptionModel } from '../../../models/video/video-caption'
import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
import { getServerActor } from '../../../helpers/utils'
import {
MAccountActor,
MAccountDefault,
MActor,
MActorLight,
MChannelActor,
MChannelDefault,
MVideoAP,
MVideoAPWithoutCaption,
MVideoPlaylistFull,
@ -49,7 +49,7 @@ async function sendUpdateVideo (videoArg: MVideoAPWithoutCaption, t: Transaction
return broadcastToFollowers(updateActivity, byActor, actorsInvolved, t)
}
async function sendUpdateActor (accountOrChannel: MAccountActor | MChannelActor, t: Transaction) {
async function sendUpdateActor (accountOrChannel: MChannelDefault | MAccountDefault, t: Transaction) {
const byActor = accountOrChannel.Actor
logger.info('Creating job to update actor %s.', byActor.url)

View File

@ -267,7 +267,7 @@ const videoPlaylistElementAPGetValidator = [
return res.status(403).end()
}
res.locals.videoPlaylistElement = videoPlaylistElement
res.locals.videoPlaylistElementAP = videoPlaylistElement
return next()
}

View File

@ -32,7 +32,7 @@ import { FindOptions, IncludeOptions, Op, Transaction, WhereOptions } from 'sequ
import { AccountBlocklistModel } from './account-blocklist'
import { ServerBlocklistModel } from '../server/server-blocklist'
import { ActorFollowModel } from '../activitypub/actor-follow'
import { MAccountActor, MAccountDefault, MAccountSummaryFormattable, MAccountFormattable } from '../../typings/models'
import { MAccountActor, MAccountDefault, MAccountSummaryFormattable, MAccountFormattable, MAccountAP } from '../../typings/models'
import * as Bluebird from 'bluebird'
export enum ScopeNames {
@ -380,7 +380,7 @@ export class AccountModel extends Model<AccountModel> {
}
}
toActivityPubObject () {
toActivityPubObject (this: MAccountAP) {
const obj = this.Actor.toActivityPubObject(this.name, 'Account')
return Object.assign(obj, {

View File

@ -39,12 +39,13 @@ import { VideoModel } from '../video/video'
import {
MActor,
MActorAccountChannelId,
MActorAP,
MActorFormattable,
MActorFull, MActorHost,
MActorFull,
MActorHost,
MActorRedundancyAllowedOpt,
MActorServer,
MActorSummaryFormattable,
MServerHost,
MActorRedundancyAllowed
MActorSummaryFormattable
} from '../../typings/models'
import * as Bluebird from 'bluebird'
@ -429,7 +430,7 @@ export class ActorModel extends Model<ActorModel> {
})
}
toActivityPubObject (name: string, type: 'Account' | 'Application' | 'VideoChannel') {
toActivityPubObject (this: MActorAP, name: string, type: 'Account' | 'Application' | 'VideoChannel') {
let activityPubType
if (type === 'Account') {
activityPubType = 'Person' as 'Person'
@ -528,7 +529,7 @@ export class ActorModel extends Model<ActorModel> {
return this.Server ? this.Server.host : WEBSERVER.HOST
}
getRedundancyAllowed (this: MActorRedundancyAllowed) {
getRedundancyAllowed () {
return this.Server ? this.Server.redundancyAllowed : false
}

View File

@ -30,7 +30,7 @@ import * as Bluebird from 'bluebird'
import { col, FindOptions, fn, literal, Op, Transaction } from 'sequelize'
import { VideoStreamingPlaylistModel } from '../video/video-streaming-playlist'
import { CONFIG } from '../../initializers/config'
import { MVideoRedundancy, MVideoRedundancyVideo } from '@server/typings/models'
import { MVideoRedundancy, MVideoRedundancyAP, MVideoRedundancyVideo } from '@server/typings/models'
export enum ScopeNames {
WITH_VIDEO = 'WITH_VIDEO'
@ -488,7 +488,7 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
return !!this.strategy
}
toActivityPubObject (): CacheFileObject {
toActivityPubObject (this: MVideoRedundancyAP): CacheFileObject {
if (this.VideoStreamingPlaylist) {
return {
id: this.url,

View File

@ -37,7 +37,10 @@ import * as Bluebird from 'bluebird'
import {
MChannelAccountDefault,
MChannelActor,
MChannelActorAccountDefaultVideos, MChannelSummaryFormattable, MChannelFormattable
MChannelActorAccountDefaultVideos,
MChannelAP,
MChannelFormattable,
MChannelSummaryFormattable
} from '../../typings/models/video'
// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
@ -513,7 +516,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
return Object.assign(actor, videoChannel)
}
toActivityPubObject (): ActivityPubActor {
toActivityPubObject (this: MChannelAP): ActivityPubActor {
const obj = this.Actor.toActivityPubObject(this.name, 'VideoChannel')
return Object.assign(obj, {

View File

@ -17,6 +17,7 @@ import { FindOptions, Op, Order, ScopeOptions, Sequelize, Transaction } from 'se
import * as Bluebird from 'bluebird'
import {
MComment,
MCommentAP,
MCommentFormattable,
MCommentId,
MCommentOwner,
@ -491,7 +492,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
} as VideoComment
}
toActivityPubObject (threadParentComments: MCommentOwner[]): VideoCommentObject {
toActivityPubObject (this: MCommentAP, threadParentComments: MCommentOwner[]): VideoCommentObject {
let inReplyTo: string
// New thread, so in AS we reply to the video
if (this.inReplyToCommentId === null) {

View File

@ -16,7 +16,7 @@ import {
} from '../../lib/activitypub'
import { isArray } from '../../helpers/custom-validators/misc'
import { VideoStreamingPlaylist } from '../../../shared/models/videos/video-streaming-playlist.model'
import { MVideo, MVideoAP, MVideoFormattable, MVideoFormattableDetails } from '../../typings/models'
import { MStreamingPlaylistRedundanciesOpt, MVideo, MVideoAP, MVideoFormattable, MVideoFormattableDetails } from '../../typings/models'
import { MStreamingPlaylistRedundancies } from '../../typings/models/video/video-streaming-playlist'
import { MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file'
@ -143,7 +143,7 @@ function videoModelToFormattedDetailsJSON (video: MVideoFormattableDetails): Vid
return Object.assign(formattedJson, detailsJson)
}
function streamingPlaylistsModelToFormattedJSON (playlists: MStreamingPlaylistRedundancies[]): VideoStreamingPlaylist[] {
function streamingPlaylistsModelToFormattedJSON (playlists: MStreamingPlaylistRedundanciesOpt[]): VideoStreamingPlaylist[] {
if (isArray(playlists) === false) return []
return playlists

View File

@ -29,6 +29,7 @@ import {
MVideoPlaylistElement,
MVideoPlaylistElementAP,
MVideoPlaylistElementFormattable,
MVideoPlaylistElementVideoUrlPlaylistPrivacy,
MVideoPlaylistVideoThumbnail
} from '@server/typings/models/video/video-playlist-element'
import { MUserAccountId } from '@server/typings/models'
@ -184,7 +185,10 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
return VideoPlaylistElementModel.findByPk(playlistElementId)
}
static loadByPlaylistAndVideoForAP (playlistId: number | string, videoId: number | string): Bluebird<MVideoPlaylistElementAP> {
static loadByPlaylistAndVideoForAP (
playlistId: number | string,
videoId: number | string
): Bluebird<MVideoPlaylistElementVideoUrlPlaylistPrivacy> {
const playlistWhere = validator.isUUID('' + playlistId) ? { uuid: playlistId } : { id: playlistId }
const videoWhere = validator.isUUID('' + videoId) ? { uuid: videoId } : { id: videoId }
@ -336,7 +340,7 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
}
}
toActivityPubObject (): PlaylistElementObject {
toActivityPubObject (this: MVideoPlaylistElementAP): PlaylistElementObject {
const base: PlaylistElementObject = {
id: this.url,
type: 'PlaylistElement',

View File

@ -45,7 +45,7 @@ import { ActivityIconObject } from '../../../shared/models/activitypub/objects'
import { FindOptions, literal, Op, ScopeOptions, Transaction, WhereOptions } from 'sequelize'
import * as Bluebird from 'bluebird'
import {
MVideoPlaylistAccountThumbnail,
MVideoPlaylistAccountThumbnail, MVideoPlaylistAP,
MVideoPlaylistFormattable,
MVideoPlaylistFull,
MVideoPlaylistFullSummary,
@ -510,7 +510,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
}
}
toActivityPubObject (page: number, t: Transaction): Promise<PlaylistObject> {
toActivityPubObject (this: MVideoPlaylistAP, page: number, t: Transaction): Promise<PlaylistObject> {
const handler = (start: number, count: number) => {
return VideoPlaylistElementModel.listUrlsOfForAP(this.id, start, count, t)
}

View File

@ -127,14 +127,17 @@ import {
MUserId,
MVideoAccountLight,
MVideoAccountLightBlacklistAllFiles,
MVideoAP,
MVideoDetails,
MVideoFormattable,
MVideoFormattableDetails,
MVideoForUser,
MVideoFullLight,
MVideoIdThumbnail,
MVideoThumbnail,
MVideoWithAllFiles, MVideoWithFile,
MVideoWithRights,
MVideoFormattable
MVideoWithAllFiles,
MVideoWithFile,
MVideoWithRights
} from '../../typings/models'
import { MVideoFile, MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file'
import { MThumbnail } from '../../typings/models/video/thumbnail'
@ -1879,11 +1882,11 @@ export class VideoModel extends Model<VideoModel> {
return join(LAZY_STATIC_PATHS.PREVIEWS, preview.filename)
}
toFormattedJSON <T extends MVideoFormattable> (this: T, options?: VideoFormattingJSONOptions): Video {
toFormattedJSON (this: MVideoFormattable, options?: VideoFormattingJSONOptions): Video {
return videoModelToFormattedJSON(this, options)
}
toFormattedDetailsJSON (): VideoDetails {
toFormattedDetailsJSON (this: MVideoFormattableDetails): VideoDetails {
return videoModelToFormattedDetailsJSON(this)
}
@ -1891,7 +1894,7 @@ export class VideoModel extends Model<VideoModel> {
return videoFilesModelToFormattedJSON(this, this.VideoFiles)
}
toActivityPubObject (): VideoTorrentObject {
toActivityPubObject (this: MVideoAP): VideoTorrentObject {
return videoModelToActivityPubObject(this)
}

View File

@ -22,7 +22,7 @@ import {
import { MVideoPlaylistFull, MVideoPlaylistFullSummary } from './models/video/video-playlist'
import { MVideoImportDefault } from '@server/typings/models/video/video-import'
import { MAccountBlocklist, MStreamingPlaylist, MVideoFile } from '@server/typings/models'
import { MVideoPlaylistElement } from '@server/typings/models/video/video-playlist-element'
import { MVideoPlaylistElement, MVideoPlaylistElementVideoUrlPlaylistPrivacy } from '@server/typings/models/video/video-playlist-element'
import { MAccountVideoRateAccountVideo } from '@server/typings/models/video/video-rate'
import { MVideoChangeOwnershipFull } from './models/video/video-change-ownership'
import { MPlugin, MServer } from '@server/typings/models/server'
@ -59,6 +59,7 @@ declare module 'express' {
videoPlaylistSummary?: MVideoPlaylistFullSummary
videoPlaylistElement?: MVideoPlaylistElement
videoPlaylistElementAP?: MVideoPlaylistElementVideoUrlPlaylistPrivacy
accountVideoRate?: MAccountVideoRateAccountVideo

View File

@ -1,6 +1,7 @@
import { AccountModel } from '../../../models/account/account'
import {
MActor,
MActorAP,
MActorAPI,
MActorAudience,
MActorDefault,
@ -89,3 +90,6 @@ export type MAccountSummaryFormattable = FunctionProperties<MAccount> &
export type MAccountFormattable = FunctionProperties<MAccount> &
Pick<MAccount, 'id' | 'name' | 'description' | 'createdAt' | 'updatedAt' | 'userId'> &
Use<'Actor', MActorFormattable>
export type MAccountAP = Pick<MAccount, 'name' | 'description'> &
Use<'Actor', MActorAP>

View File

@ -1,5 +1,5 @@
import { ActorModel } from '../../../models/activitypub/actor'
import { FunctionProperties, PickWith } from '../../utils'
import { FunctionProperties, PickWith, PickWithOpt } from '../../utils'
import { MAccount, MAccountDefault, MAccountId, MAccountIdActor } from './account'
import { MServer, MServerHost, MServerHostBlocks, MServerRedundancyAllowed } from '../server'
import { MAvatar, MAvatarFormattable } from './avatar'
@ -29,7 +29,7 @@ export type MActorLight = Omit<MActor, 'privateKey' | 'privateKey'>
// Some association attributes
export type MActorHost = Use<'Server', MServerHost>
export type MActorRedundancyAllowed = Use<'Server', MServerRedundancyAllowed>
export type MActorRedundancyAllowedOpt = PickWithOpt<ActorModel, 'Server', MServerRedundancyAllowed>
export type MActorDefaultLight = MActorLight &
Use<'Server', MServerHost> &
@ -115,4 +115,7 @@ export type MActorSummaryFormattable = FunctionProperties<MActor> &
export type MActorFormattable = MActorSummaryFormattable &
Pick<MActor, 'id' | 'followingCount' | 'followersCount' | 'createdAt' | 'updatedAt'> &
Use<'Server', MServer>
Use<'Server', MServerHost & Partial<Pick<MServer, 'redundancyAllowed'>>>
export type MActorAP = MActor &
Use<'Avatar', MAvatar>

View File

@ -8,16 +8,18 @@ import {
MAccountLight,
MAccountSummaryBlocks,
MAccountSummaryFormattable,
MAccountUrl,
MAccountUserId,
MActor,
MActorAccountChannelId,
MActorAP,
MActorAPI,
MActorDefault,
MActorDefaultLight,
MActorFormattable,
MActorLight,
MActorSummary,
MActorSummaryFormattable
MActorSummaryFormattable, MActorUrl
} from '../account'
import { MVideo } from './video'
@ -42,6 +44,8 @@ export type MChannelUserId = Pick<MChannel, 'accountId'> &
export type MChannelActor = MChannel &
Use<'Actor', MActor>
export type MChannelUrl = Use<'Actor', MActorUrl>
// Default scope
export type MChannelDefault = MChannel &
Use<'Actor', MActorDefault>
@ -116,3 +120,7 @@ export type MChannelFormattable = FunctionProperties<MChannel> &
Pick<MChannel, 'id' | 'name' | 'description' | 'createdAt' | 'updatedAt' | 'support'> &
Use<'Actor', MActorFormattable> &
PickWithOpt<VideoChannelModel, 'Account', MAccountFormattable>
export type MChannelAP = Pick<MChannel, 'name' | 'description' | 'support'> &
Use<'Actor', MActorAP> &
Use<'Account', MAccountUrl>

View File

@ -1,7 +1,7 @@
import { VideoCommentModel } from '../../../models/video/video-comment'
import { PickWith } from '../../utils'
import { MAccountDefault, MAccountFormattable } from '../account'
import { MVideoAccountLight, MVideoFeed, MVideoIdUrl } from './video'
import { PickWith, PickWithOpt } from '../../utils'
import { MAccountDefault, MAccountFormattable, MAccountUrl, MActorUrl } from '../account'
import { MVideoAccountLight, MVideoFeed, MVideoIdUrl, MVideoUrl } from './video'
type Use<K extends keyof VideoCommentModel, M> = PickWith<VideoCommentModel, K, M>
@ -10,6 +10,7 @@ type Use<K extends keyof VideoCommentModel, M> = PickWith<VideoCommentModel, K,
export type MComment = Omit<VideoCommentModel, 'OriginVideoComment' | 'InReplyToVideoComment' | 'Video' | 'Account'>
export type MCommentTotalReplies = MComment & { totalReplies?: number }
export type MCommentId = Pick<MComment, 'id'>
export type MCommentUrl = Pick<MComment, 'url'>
// ############################################################################
@ -49,3 +50,8 @@ export type MCommentAPI = MComment & { totalReplies: number }
export type MCommentFormattable = MCommentTotalReplies &
Use<'Account', MAccountFormattable>
export type MCommentAP = MComment &
Use<'Account', MAccountUrl> &
PickWithOpt<VideoCommentModel, 'Video', MVideoUrl> &
PickWithOpt<VideoCommentModel, 'InReplyToVideoComment', MCommentUrl>

View File

@ -19,11 +19,7 @@ export type MVideoPlaylistElementLight = Pick<MVideoPlaylistElement, 'id' | 'vid
export type MVideoPlaylistVideoThumbnail = MVideoPlaylistElement &
Use<'Video', MVideoThumbnail>
// ############################################################################
// For API
export type MVideoPlaylistElementAP = MVideoPlaylistElement &
export type MVideoPlaylistElementVideoUrlPlaylistPrivacy = MVideoPlaylistElement &
Use<'Video', MVideoUrl> &
Use<'VideoPlaylist', MVideoPlaylistPrivacy>
@ -33,3 +29,6 @@ export type MVideoPlaylistElementAP = MVideoPlaylistElement &
export type MVideoPlaylistElementFormattable = MVideoPlaylistElement &
Use<'Video', MVideoFormattable>
export type MVideoPlaylistElementAP = MVideoPlaylistElement &
Use<'Video', MVideoUrl>

View File

@ -2,7 +2,7 @@ import { VideoPlaylistModel } from '../../../models/video/video-playlist'
import { PickWith } from '../../utils'
import { MAccount, MAccountDefault, MAccountSummary, MAccountSummaryFormattable } from '../account'
import { MThumbnail } from './thumbnail'
import { MChannelDefault, MChannelSummary, MChannelSummaryFormattable } from './video-channels'
import { MChannelDefault, MChannelSummary, MChannelSummaryFormattable, MChannelUrl } from './video-channels'
import { MVideoPlaylistElementLight } from '@server/typings/models/video/video-playlist-element'
type Use<K extends keyof VideoPlaylistModel, M> = PickWith<VideoPlaylistModel, K, M>
@ -86,3 +86,7 @@ export type MVideoPlaylistFullSummary = MVideoPlaylist &
export type MVideoPlaylistFormattable = MVideoPlaylistVideosLength &
Use<'OwnerAccount', MAccountSummaryFormattable> &
Use<'VideoChannel', MChannelSummaryFormattable>
export type MVideoPlaylistAP = MVideoPlaylist &
Use<'Thumbnail', MThumbnail> &
Use<'VideoChannel', MChannelUrl>

View File

@ -1,6 +1,10 @@
import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy'
import { PickWith } from '@server/typings/utils'
import { MStreamingPlaylistVideo, MVideoFile, MVideoFileVideo } from '@server/typings/models'
import { PickWith, PickWithOpt } from '@server/typings/utils'
import { MStreamingPlaylistVideo, MVideoFile, MVideoFileVideo, MVideoUrl } from '@server/typings/models'
import { VideoStreamingPlaylist } from '../../../../shared/models/videos/video-streaming-playlist.model'
import { VideoStreamingPlaylistModel } from '@server/models/video/video-streaming-playlist'
import { VideoFile } from '../../../../shared/models/videos'
import { VideoFileModel } from '@server/models/video/video-file'
type Use<K extends keyof VideoRedundancyModel, M> = PickWith<VideoRedundancyModel, K, M>
@ -24,3 +28,11 @@ export type MVideoRedundancyStreamingPlaylistVideo = MVideoRedundancy &
export type MVideoRedundancyVideo = MVideoRedundancy &
Use<'VideoFile', MVideoFileVideo> &
Use<'VideoStreamingPlaylist', MStreamingPlaylistVideo>
// ############################################################################
// Format for API or AP object
export type MVideoRedundancyAP = MVideoRedundancy &
PickWithOpt<VideoRedundancyModel, 'VideoFile', MVideoFile & PickWith<VideoFileModel, 'Video', MVideoUrl>> &
PickWithOpt<VideoRedundancyModel, 'VideoStreamingPlaylist', PickWith<VideoStreamingPlaylistModel, 'Video', MVideoUrl>>

View File

@ -1,7 +1,7 @@
import { VideoStreamingPlaylistModel } from '../../../models/video/video-streaming-playlist'
import { PickWith } from '../../utils'
import { PickWith, PickWithOpt } from '../../utils'
import { MVideoRedundancyFileUrl } from './video-redundancy'
import { MVideo } from '@server/typings/models'
import { MVideo, MVideoUrl } from '@server/typings/models'
type Use<K extends keyof VideoStreamingPlaylistModel, M> = PickWith<VideoStreamingPlaylistModel, K, M>
@ -14,3 +14,6 @@ export type MStreamingPlaylistVideo = MStreamingPlaylist &
export type MStreamingPlaylistRedundancies = MStreamingPlaylist &
Use<'RedundancyVideos', MVideoRedundancyFileUrl[]>
export type MStreamingPlaylistRedundanciesOpt = MStreamingPlaylist &
PickWithOpt<VideoStreamingPlaylistModel, 'RedundancyVideos', MVideoRedundancyFileUrl[]>

View File

@ -10,7 +10,7 @@ import {
} from './video-channels'
import { MTag } from './tag'
import { MVideoCaptionLanguage } from './video-caption'
import { MStreamingPlaylist, MStreamingPlaylistRedundancies } from './video-streaming-playlist'
import { MStreamingPlaylist, MStreamingPlaylistRedundancies, MStreamingPlaylistRedundanciesOpt } from './video-streaming-playlist'
import { MVideoFile, MVideoFileRedundanciesOpt } from './video-file'
import { MThumbnail } from './thumbnail'
import { MVideoBlacklist, MVideoBlacklistLight, MVideoBlacklistUnfederated } from './video-blacklist'
@ -165,5 +165,5 @@ export type MVideoFormattable = MVideo &
export type MVideoFormattableDetails = MVideoFormattable &
Use<'VideoChannel', MChannelFormattable> &
Use<'Tags', MTag[]> &
Use<'VideoStreamingPlaylists', MStreamingPlaylistRedundancies[]> &
Use<'VideoStreamingPlaylists', MStreamingPlaylistRedundanciesOpt[]> &
Use<'VideoFiles', MVideoFileRedundanciesOpt[]>