Cleanup model types
authorChocobozzz <me@florianbigard.com>
Tue, 20 Aug 2019 11:52:49 +0000 (13:52 +0200)
committerChocobozzz <me@florianbigard.com>
Tue, 20 Aug 2019 12:53:42 +0000 (14:53 +0200)
50 files changed:
server/controllers/api/search.ts
server/controllers/api/videos/import.ts
server/helpers/middlewares/video-channels.ts
server/helpers/middlewares/videos.ts
server/helpers/video.ts
server/lib/activitypub/actor.ts
server/lib/activitypub/process/process-announce.ts
server/lib/activitypub/process/process-create.ts
server/lib/activitypub/video-comments.ts
server/lib/activitypub/videos.ts
server/lib/avatar.ts
server/lib/emailer.ts
server/lib/job-queue/handlers/activitypub-follow.ts
server/lib/job-queue/handlers/video-import.ts
server/lib/notifier.ts
server/lib/schedulers/videos-redundancy-scheduler.ts
server/middlewares/validators/videos/video-channels.ts
server/middlewares/validators/videos/videos.ts
server/models/account/user.ts
server/models/video/video-channel.ts
server/models/video/video.ts
server/typings/express.ts
server/typings/models/account/account-blocklist.ts
server/typings/models/account/account.ts
server/typings/models/account/actor-follow.ts
server/typings/models/account/actor.ts
server/typings/models/index.d.ts
server/typings/models/oauth/index.d.ts [new file with mode: 0644]
server/typings/models/oauth/oauth-token.ts
server/typings/models/server/server-blocklist.ts
server/typings/models/server/server.ts
server/typings/models/user/index.d.ts
server/typings/models/user/user-notification.ts
server/typings/models/user/user.ts
server/typings/models/video/index.d.ts
server/typings/models/video/video-abuse.ts
server/typings/models/video/video-blacklist.ts
server/typings/models/video/video-caption.ts
server/typings/models/video/video-change-ownership.ts
server/typings/models/video/video-channels.ts
server/typings/models/video/video-comment.ts
server/typings/models/video/video-file.ts
server/typings/models/video/video-import.ts
server/typings/models/video/video-playlist-element.ts
server/typings/models/video/video-playlist.ts
server/typings/models/video/video-rate.ts
server/typings/models/video/video-redundancy.ts
server/typings/models/video/video-share.ts
server/typings/models/video/video-streaming-playlist.ts
server/typings/models/video/video.ts

index 7fef7c1732709bc3eef8fce8058fe2464a1c3cfe..349650aca65e290c53b33794cb895a550dd60da3 100644 (file)
@@ -19,7 +19,7 @@ import { getOrCreateActorAndServerAndModel, getOrCreateVideoAndAccountAndChannel
 import { logger } from '../../helpers/logger'
 import { VideoChannelModel } from '../../models/video/video-channel'
 import { loadActorUrlOrGetFromWebfinger } from '../../helpers/webfinger'
-import { MChannelAccountDefault, MVideoAccountAllFiles } from '../../typings/models'
+import { MChannelAccountDefault, MVideoAccountLightBlacklistAllFiles } from '../../typings/models'
 
 const searchRouter = express.Router()
 
@@ -138,7 +138,7 @@ async function searchVideosDB (query: VideosSearchQuery, res: express.Response)
 }
 
 async function searchVideoURI (url: string, res: express.Response) {
-  let video: MVideoAccountAllFiles
+  let video: MVideoAccountLightBlacklistAllFiles
 
   // Check if we can fetch a remote video with the URL
   if (isUserAbleToSearchRemoteURI(res)) {
index a058b37efa60d8d02b0e73af860d899266b0aaf5..e7adcc35a2597ebaa1adafb875202135e8ee9827 100644 (file)
@@ -25,7 +25,7 @@ import { sequelizeTypescript } from '../../../initializers/database'
 import { createVideoMiniatureFromExisting } from '../../../lib/thumbnail'
 import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type'
 import {
-  MChannelActorAccountDefault,
+  MChannelAccountDefault,
   MThumbnail,
   MUser,
   MVideoTag,
@@ -234,7 +234,7 @@ function insertIntoDB (parameters: {
   video: MVideoThumbnailAccountDefault,
   thumbnailModel: MThumbnail,
   previewModel: MThumbnail,
-  videoChannel: MChannelActorAccountDefault,
+  videoChannel: MChannelAccountDefault,
   tags: string[],
   videoImportAttributes: Partial<MVideoImport>,
   user: MUser
index 17b7692c575c9698e577a48f189a98ca3509dde6..1595ecd94626af0ac05150dae72e9f1aed721d65 100644 (file)
@@ -1,6 +1,6 @@
 import * as express from 'express'
 import { VideoChannelModel } from '../../models/video/video-channel'
-import { MChannelActorAccountDefault } from '../../typings/models'
+import { MChannelAccountDefault } from '@server/typings/models'
 
 async function doesLocalVideoChannelNameExist (name: string, res: express.Response) {
   const videoChannel = await VideoChannelModel.loadLocalByNameAndPopulateAccount(name)
@@ -28,7 +28,7 @@ export {
   doesVideoChannelNameWithHostExist
 }
 
-function processVideoChannelExist (videoChannel: MChannelActorAccountDefault, res: express.Response) {
+function processVideoChannelExist (videoChannel: MChannelAccountDefault, res: express.Response) {
   if (!videoChannel) {
     res.status(404)
        .json({ error: 'Video channel not found' })
index 964f0c91a1a7eb2ea32f6cf53efa57dd9f2a7718..74f529804e7abeb30494f064f1fdd59743d3c9a2 100644 (file)
@@ -2,7 +2,7 @@ import { Response } from 'express'
 import { fetchVideo, VideoFetchType } from '../video'
 import { UserRight } from '../../../shared/models/users'
 import { VideoChannelModel } from '../../models/video/video-channel'
-import { MUser, MUserAccountId, MVideoAccountLight, MVideoFullLight, MVideoWithRights } from '@server/typings/models'
+import { MUser, MUserAccountId, MVideoAccountLight, MVideoFullLight, MVideoThumbnail, MVideoWithRights } from '@server/typings/models'
 
 async function doesVideoExist (id: number | string, res: Response, fetchType: VideoFetchType = 'all') {
   const userId = res.locals.oauth ? res.locals.oauth.token.User.id : undefined
@@ -27,7 +27,7 @@ async function doesVideoExist (id: number | string, res: Response, fetchType: Vi
       break
 
     case 'only-video':
-      res.locals.onlyVideo = video
+      res.locals.onlyVideo = video as MVideoThumbnail
       break
 
     case 'only-video-with-rights':
index 26a72ac5c593162361bac2a6b9776460b9c9a3fa..d066e2b1f42854ce5c110f79955a8226606a93d9 100644 (file)
@@ -1,6 +1,12 @@
 import { VideoModel } from '../models/video/video'
 import * as Bluebird from 'bluebird'
-import { MVideoAccountAllFiles, MVideoFullLight, MVideoThumbnail, MVideoWithRights, MVideoIdThumbnail } from '@server/typings/models'
+import {
+  MVideoAccountLightBlacklistAllFiles,
+  MVideoFullLight,
+  MVideoIdThumbnail,
+  MVideoThumbnail,
+  MVideoWithRights
+} from '@server/typings/models'
 import { Response } from 'express'
 
 type VideoFetchType = 'all' | 'only-video' | 'only-video-with-rights' | 'id' | 'none'
@@ -30,10 +36,10 @@ function fetchVideo (
 
 type VideoFetchByUrlType = 'all' | 'only-video'
 
-function fetchVideoByUrl (url: string, fetchType: 'all'): Bluebird<MVideoAccountAllFiles>
+function fetchVideoByUrl (url: string, fetchType: 'all'): Bluebird<MVideoAccountLightBlacklistAllFiles>
 function fetchVideoByUrl (url: string, fetchType: 'only-video'): Bluebird<MVideoThumbnail>
-function fetchVideoByUrl (url: string, fetchType: VideoFetchByUrlType): Bluebird<MVideoAccountAllFiles> | Bluebird<MVideoThumbnail>
-function fetchVideoByUrl (url: string, fetchType: VideoFetchByUrlType): Bluebird<MVideoAccountAllFiles> | Bluebird<MVideoThumbnail> {
+function fetchVideoByUrl (url: string, fetchType: VideoFetchByUrlType): Bluebird<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail>
+function fetchVideoByUrl (url: string, fetchType: VideoFetchByUrlType): Bluebird<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail> {
   if (fetchType === 'all') return VideoModel.loadByUrlAndPopulateAccount(url)
 
   if (fetchType === 'only-video') return VideoModel.loadByUrl(url)
@@ -43,10 +49,15 @@ function getVideo (res: Response) {
   return res.locals.videoAll || res.locals.onlyVideo || res.locals.onlyVideoWithRights || res.locals.videoId
 }
 
+function getVideoWithAttributes (res: Response) {
+  return res.locals.videoAll || res.locals.onlyVideo || res.locals.onlyVideoWithRights
+}
+
 export {
   VideoFetchType,
   VideoFetchByUrlType,
   fetchVideo,
   getVideo,
+  getVideoWithAttributes,
   fetchVideoByUrl
 }
index 7862b0f004d56660458e8b7d86e9127d4d819118..5201bdeef392a2ed0c948495b56749f2a5f92877 100644 (file)
@@ -24,15 +24,17 @@ import { ActorFetchByUrlType, fetchActorByUrl } from '../../helpers/actor'
 import { sequelizeTypescript } from '../../initializers/database'
 import {
   MAccount,
+  MAccountDefault,
   MActor,
   MActorAccountChannelId,
+  MActorAccountChannelIdActor,
   MActorAccountId,
   MActorDefault,
   MActorFull,
+  MActorFullActor,
   MActorId,
-  MActorAccountChannelIdActor,
   MChannel,
-  MActorFullActor, MAccountActorDefault, MChannelActorDefault, MChannelActorAccountDefault
+  MChannelAccountDefault
 } from '../../typings/models'
 
 // Set account keys, this could be long so process after the account creation and do not block the client
@@ -374,12 +376,11 @@ function saveActorAndServerAndModelIfNotExist (
     })
 
     if (actorCreated.type === 'Person' || actorCreated.type === 'Application') {
-      actorCreated.Account = await saveAccount(actorCreated, result, t) as MAccountActorDefault
+      actorCreated.Account = await saveAccount(actorCreated, result, t) as MAccountDefault
       actorCreated.Account.Actor = actorCreated
     } else if (actorCreated.type === 'Group') { // Video channel
-      actorCreated.VideoChannel = await saveVideoChannel(actorCreated, result, ownerActor, t) as MChannelActorAccountDefault
-      actorCreated.VideoChannel.Actor = actorCreated
-      actorCreated.VideoChannel.Account = ownerActor.Account
+      const channel = await saveVideoChannel(actorCreated, result, ownerActor, t)
+      actorCreated.VideoChannel = Object.assign(channel, { Actor: actorCreated, Account: ownerActor.Account })
     }
 
     actorCreated.Server = server
index 91a9ad72c3f4b7a50b06c167f175d49252dc89d2..7e22125d5ce644a64b7bbc527b2576f51eceebb0 100644 (file)
@@ -7,7 +7,7 @@ import { getOrCreateVideoAndAccountAndChannel } from '../videos'
 import { Notifier } from '../../notifier'
 import { logger } from '../../../helpers/logger'
 import { APProcessorOptions } from '../../../typings/activitypub-processor.model'
-import { MActorSignature, MVideoAccountAllFiles } from '../../../typings/models'
+import { MActorSignature, MVideoAccountLightBlacklistAllFiles } from '../../../typings/models'
 
 async function processAnnounceActivity (options: APProcessorOptions<ActivityAnnounce>) {
   const { activity, byActor: actorAnnouncer } = options
@@ -28,7 +28,7 @@ export {
 async function processVideoShare (actorAnnouncer: MActorSignature, activity: ActivityAnnounce, notify: boolean) {
   const objectUri = typeof activity.object === 'string' ? activity.object : activity.object.id
 
-  let video: MVideoAccountAllFiles
+  let video: MVideoAccountLightBlacklistAllFiles
   let videoCreated: boolean
 
   try {
index c45f09f52fd9eea5acee483348e00a9dc039a4a7..bee853721033b4d8dfecdaba321f8eb7a485f0d9 100644 (file)
@@ -11,7 +11,7 @@ import { Notifier } from '../../notifier'
 import { PlaylistObject } from '../../../../shared/models/activitypub/objects/playlist-object'
 import { createOrUpdateVideoPlaylist } from '../playlist'
 import { APProcessorOptions } from '../../../typings/activitypub-processor.model'
-import { MActorSignature, MCommentOwnerVideo, MVideoAccountAllFiles } from '../../../typings/models'
+import { MActorSignature, MCommentOwnerVideo, MVideoAccountLightBlacklistAllFiles } from '../../../typings/models'
 
 async function processCreateActivity (options: APProcessorOptions<ActivityCreate>) {
   const { activity, byActor } = options
@@ -81,7 +81,7 @@ async function processCreateVideoComment (activity: ActivityCreate, byActor: MAc
 
   if (!byAccount) throw new Error('Cannot create video comment with the non account actor ' + byActor.url)
 
-  let video: MVideoAccountAllFiles
+  let video: MVideoAccountLightBlacklistAllFiles
   let created: boolean
   let comment: MCommentOwnerVideo
   try {
index 375ac0aad4cff122485cc8baa71fc7d6df059d60..3e8306fa4c6ecf117adbc477e410b6f3bbc68d4c 100644 (file)
@@ -7,7 +7,7 @@ import { getOrCreateActorAndServerAndModel } from './actor'
 import { getOrCreateVideoAndAccountAndChannel } from './videos'
 import * as Bluebird from 'bluebird'
 import { checkUrlsSameHost } from '../../helpers/activitypub'
-import { MCommentOwner, MCommentOwnerVideo, MVideoAccountAllFiles } from '../../typings/models/video'
+import { MCommentOwner, MCommentOwnerVideo, MVideoAccountLightBlacklistAllFiles } from '../../typings/models/video'
 
 type ResolveThreadParams = {
   url: string,
@@ -15,7 +15,7 @@ type ResolveThreadParams = {
   isVideo?: boolean,
   commentCreated?: boolean
 }
-type ResolveThreadResult = Promise<{ video: MVideoAccountAllFiles, comment: MCommentOwnerVideo, commentCreated: boolean }>
+type ResolveThreadResult = Promise<{ video: MVideoAccountLightBlacklistAllFiles, comment: MCommentOwnerVideo, commentCreated: boolean }>
 
 async function addVideoComments (commentUrls: string[]) {
   return Bluebird.map(commentUrls, commentUrl => {
index 035994da835a5d48ec77e1013248b619df490d46..970a953fc43a4363efd36f112fda019528d52adc 100644 (file)
@@ -58,7 +58,7 @@ import {
   MChannelDefault,
   MChannelId,
   MVideo,
-  MVideoAccountAllFiles,
+  MVideoAccountLightBlacklistAllFiles,
   MVideoAccountLight,
   MVideoAP,
   MVideoAPWithoutCaption,
@@ -213,19 +213,19 @@ function getOrCreateVideoAndAccountAndChannel (options: {
   syncParam?: SyncParam,
   fetchType?: 'all',
   allowRefresh?: boolean
-}): Promise<{ video: MVideoAccountAllFiles, created: boolean, autoBlacklisted?: boolean }>
+}): Promise<{ video: MVideoAccountLightBlacklistAllFiles, created: boolean, autoBlacklisted?: boolean }>
 function getOrCreateVideoAndAccountAndChannel (options: {
   videoObject: { id: string } | string,
   syncParam?: SyncParam,
   fetchType?: VideoFetchByUrlType,
   allowRefresh?: boolean
-}): Promise<{ video: MVideoAccountAllFiles | MVideoThumbnail, created: boolean, autoBlacklisted?: boolean }>
+}): Promise<{ video: MVideoAccountLightBlacklistAllFiles | MVideoThumbnail, created: boolean, autoBlacklisted?: boolean }>
 async function getOrCreateVideoAndAccountAndChannel (options: {
   videoObject: { id: string } | string,
   syncParam?: SyncParam,
   fetchType?: VideoFetchByUrlType,
   allowRefresh?: boolean // true by default
-}): Promise<{ video: MVideoAccountAllFiles | MVideoThumbnail, created: boolean, autoBlacklisted?: boolean }> {
+}): Promise<{ video: MVideoAccountLightBlacklistAllFiles | MVideoThumbnail, created: boolean, autoBlacklisted?: boolean }> {
   // Default params
   const syncParam = options.syncParam || { likes: true, dislikes: true, shares: true, comments: true, thumbnail: true, refreshVideo: false }
   const fetchType = options.fetchType || 'all'
@@ -263,7 +263,7 @@ async function getOrCreateVideoAndAccountAndChannel (options: {
 }
 
 async function updateVideoFromAP (options: {
-  video: MVideoAccountAllFiles,
+  video: MVideoAccountLightBlacklistAllFiles,
   videoObject: VideoTorrentObject,
   account: MAccountActor,
   channel: MChannelDefault,
@@ -420,7 +420,7 @@ async function refreshVideoIfNeeded (options: {
 
   // We need more attributes if the argument video was fetched with not enough joints
   const video = options.fetchedType === 'all'
-    ? options.video as MVideoAccountAllFiles
+    ? options.video as MVideoAccountLightBlacklistAllFiles
     : await VideoModel.loadByUrlAndPopulateAccount(options.video.url)
 
   try {
index 9005b3e225e1270fe696f24149784421cb87b12f..ad4cdd3ab80849388a63accdba1797a4ba65482e 100644 (file)
@@ -11,11 +11,11 @@ import { sequelizeTypescript } from '../initializers/database'
 import * as LRUCache from 'lru-cache'
 import { queue } from 'async'
 import { downloadImage } from '../helpers/requests'
-import { MAccountActorDefault, MChannelActorDefault } from '../typings/models'
+import { MAccountDefault, MChannelDefault } from '../typings/models'
 
 async function updateActorAvatarFile (
   avatarPhysicalFile: Express.Multer.File,
-  accountOrChannel: MAccountActorDefault | MChannelActorDefault
+  accountOrChannel: MAccountDefault | MChannelDefault
 ) {
   const extension = extname(avatarPhysicalFile.filename)
   const avatarName = uuidv4() + extension
index fe57a3e4caf5108e3a45a03e21df766a694d1da9..a888b7a72ad0f6ac188e4642f893ebaa7aa9bd8e 100644 (file)
@@ -2,14 +2,12 @@ import { createTransport, Transporter } from 'nodemailer'
 import { isTestInstance } from '../helpers/core-utils'
 import { bunyanLogger, logger } from '../helpers/logger'
 import { CONFIG } from '../initializers/config'
-import { UserModel } from '../models/account/user'
 import { JobQueue } from './job-queue'
 import { EmailPayload } from './job-queue/handlers/email'
 import { readFileSync } from 'fs-extra'
-import { VideoBlacklistModel } from '../models/video/video-blacklist'
 import { WEBSERVER } from '../initializers/constants'
 import { MCommentOwnerVideo, MVideo, MVideoAbuseVideo, MVideoAccountLight, MVideoBlacklistVideo } from '../typings/models/video'
-import { MActorFollowActors, MActorFollowFull, MUser } from '../typings/models'
+import { MActorFollowActors, MActorFollowFollowingFullFollowerAccount, MUser } from '../typings/models'
 import { MVideoImport, MVideoImportVideo } from '@server/typings/models/video/video-import'
 
 type SendEmailOptions = {
@@ -109,7 +107,7 @@ class Emailer {
     return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
   }
 
-  addNewFollowNotification (to: string[], actorFollow: MActorFollowFull, followType: 'account' | 'channel') {
+  addNewFollowNotification (to: string[], actorFollow: MActorFollowFollowingFullFollowerAccount, followType: 'account' | 'channel') {
     const followerName = actorFollow.ActorFollower.Account.getDisplayName()
     const followingName = (actorFollow.ActorFollowing.VideoChannel || actorFollow.ActorFollowing.Account).getDisplayName()
 
index 741b1ffdefa23f52eec765cdeded47860f17f0b6..5cb55cad6109b7f825927b5780198a1e8243a699 100644 (file)
@@ -10,7 +10,7 @@ import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
 import { ActorModel } from '../../../models/activitypub/actor'
 import { Notifier } from '../../notifier'
 import { sequelizeTypescript } from '../../../initializers/database'
-import { MActorFollowFull, MActorFull } from '../../../typings/models'
+import { MAccount, MActor, MActorFollowActors, MActorFollowFull, MActorFull } from '../../../typings/models'
 
 export type ActivitypubFollowPayload = {
   followerActorId: number
@@ -45,7 +45,7 @@ export {
 
 // ---------------------------------------------------------------------------
 
-async function follow (fromActor: MActorFull, targetActor: MActorFull) {
+async function follow (fromActor: MActor, targetActor: MActorFull) {
   if (fromActor.id === targetActor.id) {
     throw new Error('Follower is the same than target actor.')
   }
@@ -54,7 +54,7 @@ async function follow (fromActor: MActorFull, targetActor: MActorFull) {
   const state = !fromActor.serverId && !targetActor.serverId ? 'accepted' : 'pending'
 
   const actorFollow = await sequelizeTypescript.transaction(async t => {
-    const [ actorFollow ] = await ActorFollowModel.findOrCreate<MActorFollowFull>({
+    const [ actorFollow ] = await ActorFollowModel.findOrCreate<MActorFollowActors>({
       where: {
         actorId: fromActor.id,
         targetActorId: targetActor.id
@@ -75,5 +75,14 @@ async function follow (fromActor: MActorFull, targetActor: MActorFull) {
     return actorFollow
   })
 
-  if (actorFollow.state === 'accepted') Notifier.Instance.notifyOfNewUserFollow(actorFollow)
+  if (actorFollow.state === 'accepted') {
+    const followerFull = Object.assign(fromActor, { Account: await actorFollow.ActorFollower.$get('Account') as MAccount })
+
+    const actorFollowFull = Object.assign(actorFollow, {
+      ActorFollowing: targetActor,
+      ActorFollower: followerFull
+    })
+
+    Notifier.Instance.notifyOfNewUserFollow(actorFollowFull)
+  }
 }
index f9dda79f83717cb0b1df430e1a4d9a34db5e2d40..ff8c9332842a0791993fffb7b7ba83ccee86a0ca 100644 (file)
@@ -111,13 +111,11 @@ type ProcessFileOptions = {
   generateThumbnail: boolean
   generatePreview: boolean
 }
-async function processFile (downloader: () => Promise<string>, videoImportArg: MVideoImportDefault, options: ProcessFileOptions) {
+async function processFile (downloader: () => Promise<string>, videoImport: MVideoImportDefault, options: ProcessFileOptions) {
   let tempVideoPath: string
   let videoDestFile: string
   let videoFile: VideoFileModel
 
-  const videoImport = videoImportArg as MVideoImportDefaultFiles
-
   try {
     // Download video from youtubeDL
     tempVideoPath = await downloader()
@@ -142,35 +140,37 @@ async function processFile (downloader: () => Promise<string>, videoImportArg: M
       videoId: videoImport.videoId
     }
     videoFile = new VideoFileModel(videoFileData)
+
+    const videoWithFiles = Object.assign(videoImport.Video, { VideoFiles: [ videoFile ] })
     // To clean files if the import fails
-    videoImport.Video.VideoFiles = [ videoFile ]
+    const videoImportWithFiles: MVideoImportDefaultFiles = Object.assign(videoImport, { Video: videoWithFiles })
 
     // Move file
-    videoDestFile = join(CONFIG.STORAGE.VIDEOS_DIR, videoImport.Video.getVideoFilename(videoFile))
+    videoDestFile = join(CONFIG.STORAGE.VIDEOS_DIR, videoImportWithFiles.Video.getVideoFilename(videoFile))
     await move(tempVideoPath, videoDestFile)
     tempVideoPath = null // This path is not used anymore
 
     // Process thumbnail
     let thumbnailModel: MThumbnail
     if (options.downloadThumbnail && options.thumbnailUrl) {
-      thumbnailModel = await createVideoMiniatureFromUrl(options.thumbnailUrl, videoImport.Video, ThumbnailType.MINIATURE)
+      thumbnailModel = await createVideoMiniatureFromUrl(options.thumbnailUrl, videoImportWithFiles.Video, ThumbnailType.MINIATURE)
     } else if (options.generateThumbnail || options.downloadThumbnail) {
-      thumbnailModel = await generateVideoMiniature(videoImport.Video, videoFile, ThumbnailType.MINIATURE)
+      thumbnailModel = await generateVideoMiniature(videoImportWithFiles.Video, videoFile, ThumbnailType.MINIATURE)
     }
 
     // Process preview
     let previewModel: MThumbnail
     if (options.downloadPreview && options.thumbnailUrl) {
-      previewModel = await createVideoMiniatureFromUrl(options.thumbnailUrl, videoImport.Video, ThumbnailType.PREVIEW)
+      previewModel = await createVideoMiniatureFromUrl(options.thumbnailUrl, videoImportWithFiles.Video, ThumbnailType.PREVIEW)
     } else if (options.generatePreview || options.downloadPreview) {
-      previewModel = await generateVideoMiniature(videoImport.Video, videoFile, ThumbnailType.PREVIEW)
+      previewModel = await generateVideoMiniature(videoImportWithFiles.Video, videoFile, ThumbnailType.PREVIEW)
     }
 
     // Create torrent
-    await videoImport.Video.createTorrentAndSetInfoHash(videoFile)
+    await videoImportWithFiles.Video.createTorrentAndSetInfoHash(videoFile)
 
     const { videoImportUpdated, video } = await sequelizeTypescript.transaction(async t => {
-      const videoImportToUpdate = videoImport as MVideoImportVideo
+      const videoImportToUpdate = videoImportWithFiles as MVideoImportVideo
 
       // Refresh video
       const video = await VideoModel.load(videoImportToUpdate.videoId, t)
index f01101b8e5de59bb0a4063845ae0a0e080dff7e8..23f76a21a413684fda8cc3cd2d4fffb2d6d497cb 100644 (file)
@@ -21,7 +21,7 @@ import {
   MVideoFullLight
 } from '../typings/models/video'
 import { MUser, MUserAccount, MUserWithNotificationSetting, UserNotificationModelForApi } from '@server/typings/models/user'
-import { MActorFollowActors, MActorFollowFull } from '../typings/models'
+import { MActorFollowActors, MActorFollowFull, MActorFollowFollowingFullFollowerAccount } from '../typings/models'
 import { ActorFollowModel } from '../models/activitypub/actor-follow'
 import { MVideoImportVideo } from '@server/typings/models/video/video-import'
 import { AccountModel } from '@server/models/account/account'
@@ -102,7 +102,7 @@ class Notifier {
         .catch(err => logger.error('Cannot notify moderators of new user registration (%s).', user.username, { err }))
   }
 
-  notifyOfNewUserFollow (actorFollow: MActorFollowFull): void {
+  notifyOfNewUserFollow (actorFollow: MActorFollowFollowingFullFollowerAccount): void {
     this.notifyUserOfNewActorFollow(actorFollow)
       .catch(err => {
         logger.error(
@@ -231,7 +231,7 @@ class Notifier {
     return this.notify({ users, settingGetter, notificationCreator, emailSender })
   }
 
-  private async notifyUserOfNewActorFollow (actorFollow: MActorFollowFull) {
+  private async notifyUserOfNewActorFollow (actorFollow: MActorFollowFollowingFullFollowerAccount) {
     if (actorFollow.ActorFollowing.isOwned() === false) return
 
     // Account follows one of our account?
index de8fc075b29a2f5a10ee48ac8570d827112fe544..d9018e6060fa8ee5c9c469eb241ed4f1e76daa50 100644 (file)
@@ -32,7 +32,9 @@ type CandidateToDuplicate = {
   streamingPlaylists: MStreamingPlaylist[]
 }
 
-function isMVideoRedundancyFileVideo (o: MVideoRedundancyVideo): o is MVideoRedundancyFileVideo {
+function isMVideoRedundancyFileVideo (
+  o: MVideoRedundancyFileVideo | MVideoRedundancyStreamingPlaylistVideo
+): o is MVideoRedundancyFileVideo {
   return !!(o as MVideoRedundancyFileVideo).VideoFile
 }
 
index a0df03f7ebc68e879d81d1aa931b37894e2a9832..d212745277336b650f5cf12ee9d265b7e7fdb3a5 100644 (file)
@@ -13,8 +13,7 @@ import { isActorPreferredUsernameValid } from '../../../helpers/custom-validator
 import { ActorModel } from '../../../models/activitypub/actor'
 import { isBooleanValid } from '../../../helpers/custom-validators/misc'
 import { doesLocalVideoChannelNameExist, doesVideoChannelNameWithHostExist } from '../../../helpers/middlewares'
-import { MChannelActorAccountDefault } from '../../../typings/models/video'
-import { MUser } from '@server/typings/models'
+import { MChannelAccountDefault, MUser } from '@server/typings/models'
 
 const videoChannelsAddValidator = [
   body('name').custom(isActorPreferredUsernameValid).withMessage('Should have a valid channel name'),
@@ -132,7 +131,7 @@ export {
 
 // ---------------------------------------------------------------------------
 
-function checkUserCanDeleteVideoChannel (user: MUser, videoChannel: MChannelActorAccountDefault, res: express.Response) {
+function checkUserCanDeleteVideoChannel (user: MUser, videoChannel: MChannelAccountDefault, res: express.Response) {
   if (videoChannel.Actor.isOwned() === false) {
     res.status(403)
               .json({ error: 'Cannot remove video channel of another server.' })
index a194d14b3a529f4f9d623bbd1fbfd64ac5284479..1449903b7d8798e4f7cd4f5bd389391df34b0a99 100644 (file)
@@ -44,7 +44,7 @@ import { isLocalVideoAccepted } from '../../../lib/moderation'
 import { Hooks } from '../../../lib/plugins/hooks'
 import { checkUserCanManageVideo, doesVideoChannelOfAccountExist, doesVideoExist } from '../../../helpers/middlewares'
 import { MVideoFullLight } from '@server/typings/models'
-import { getVideo } from '../../../helpers/video'
+import { getVideoWithAttributes } from '../../../helpers/video'
 
 const videosAddValidator = getCommonVideoEditAttributes().concat([
   body('videofile')
@@ -123,7 +123,7 @@ const videosUpdateValidator = getCommonVideoEditAttributes().concat([
 ])
 
 async function checkVideoFollowConstraints (req: express.Request, res: express.Response, next: express.NextFunction) {
-  const video = getVideo(res)
+  const video = getVideoWithAttributes(res)
 
   // Anybody can watch local videos
   if (video.isOwned() === true) return next()
@@ -157,7 +157,7 @@ const videosCustomGetValidator = (fetchType: 'all' | 'only-video' | 'only-video-
       if (areValidationErrors(req, res)) return
       if (!await doesVideoExist(req.params.id, res, fetchType)) return
 
-      const video = getVideo(res)
+      const video = getVideoWithAttributes(res)
       const videoAll = video as MVideoFullLight
 
       // Video private or blacklisted
index 24b1626e77f17aa490ed31fb2c4372cd674b6b10..cb54d79af35dd1547f3ff72277887695c66da0d4 100644 (file)
@@ -55,7 +55,7 @@ import { UserAdminFlag } from '../../../shared/models/users/user-flag.model'
 import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
 import { getThemeOrDefault } from '../../lib/plugins/theme-utils'
 import * as Bluebird from 'bluebird'
-import { MUserChannel, MUserDefault, MUserId, MUserWithNotificationSetting } from '@server/typings/models'
+import { MUserNotifSettingChannelDefault, MUserDefault, MUserId, MUserWithNotificationSetting } from '@server/typings/models'
 
 enum ScopeNames {
   WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL'
@@ -384,7 +384,7 @@ export class UserModel extends Model<UserModel> {
     return UserModel.findOne(query)
   }
 
-  static loadByUsernameAndPopulateChannels (username: string): Bluebird<MUserChannel> {
+  static loadByUsernameAndPopulateChannels (username: string): Bluebird<MUserNotifSettingChannelDefault> {
     const query = {
       where: {
         username: { [ Op.iLike ]: username }
index 79b9e7d2ba1e83190e4e3a975ff98dd873e01536..b6a60827fa115c204b34f19754e1dde01f4f08aa 100644 (file)
@@ -37,7 +37,6 @@ import * as Bluebird from 'bluebird'
 import {
   MChannelAccountDefault,
   MChannelActor,
-  MChannelActorAccountDefault,
   MChannelActorAccountDefaultVideos
 } from '../../typings/models/video'
 
@@ -376,13 +375,13 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
       })
   }
 
-  static loadByIdAndPopulateAccount (id: number): Bluebird<MChannelActorAccountDefault> {
+  static loadByIdAndPopulateAccount (id: number): Bluebird<MChannelAccountDefault> {
     return VideoChannelModel.unscoped()
       .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
       .findByPk(id)
   }
 
-  static loadByIdAndAccount (id: number, accountId: number): Bluebird<MChannelActorAccountDefault> {
+  static loadByIdAndAccount (id: number, accountId: number): Bluebird<MChannelAccountDefault> {
     const query = {
       where: {
         id,
@@ -395,7 +394,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
       .findOne(query)
   }
 
-  static loadAndPopulateAccount (id: number): Bluebird<MChannelActorAccountDefault> {
+  static loadAndPopulateAccount (id: number): Bluebird<MChannelAccountDefault> {
     return VideoChannelModel.unscoped()
       .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
       .findByPk(id)
@@ -427,7 +426,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
     return VideoChannelModel.loadByNameAndHostAndPopulateAccount(name, host)
   }
 
-  static loadLocalByNameAndPopulateAccount (name: string): Bluebird<MChannelActorAccountDefault> {
+  static loadLocalByNameAndPopulateAccount (name: string): Bluebird<MChannelAccountDefault> {
     const query = {
       include: [
         {
@@ -446,7 +445,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
       .findOne(query)
   }
 
-  static loadByNameAndHostAndPopulateAccount (name: string, host: string): Bluebird<MChannelActorAccountDefault> {
+  static loadByNameAndHostAndPopulateAccount (name: string, host: string): Bluebird<MChannelAccountDefault> {
     const query = {
       include: [
         {
index 7b1f0bc316b698cc8403b8725079cbfa46c72a9f..e62bde344f15182a884641d6c188711265e3bc24 100644 (file)
@@ -121,18 +121,18 @@ import { createTorrentPromise } from '../../helpers/webtorrent'
 import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type'
 import {
   MChannel,
-  MChannelActorAccountDefault,
+  MChannelAccountDefault,
   MChannelId,
   MUserAccountId,
   MUserId,
-  MVideoAccountAllFiles,
   MVideoAccountLight,
+  MVideoAccountLightBlacklistAllFiles,
   MVideoDetails,
+  MVideoForUser,
   MVideoFullLight,
   MVideoIdThumbnail,
   MVideoThumbnail,
   MVideoWithAllFiles,
-  MVideoWithBlacklistThumbnailScheduled,
   MVideoWithRights
 } from '../../typings/models'
 import { MVideoFile, MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file'
@@ -1015,7 +1015,7 @@ export class VideoModel extends Model<VideoModel> {
             AccountModel
           ],
           transaction: options.transaction
-        }) as MChannelActorAccountDefault
+        }) as MChannelAccountDefault
       }
 
       return sendDeleteVideo(instance, options.transaction)
@@ -1209,10 +1209,10 @@ export class VideoModel extends Model<VideoModel> {
 
     return Promise.all([
       VideoModel.count(countQuery),
-      VideoModel.scope(findScopes).findAll(findQuery)
+      VideoModel.scope(findScopes).findAll<MVideoForUser>(findQuery)
     ]).then(([ count, rows ]) => {
       return {
-        data: rows as MVideoWithBlacklistThumbnailScheduled[],
+        data: rows,
         total: count
       }
     })
@@ -1468,7 +1468,7 @@ export class VideoModel extends Model<VideoModel> {
     return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(query)
   }
 
-  static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction): Bluebird<MVideoAccountAllFiles> {
+  static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction): Bluebird<MVideoAccountLightBlacklistAllFiles> {
     const query: FindOptions = {
       where: {
         url
index 26009146110c0702dc36ccee4b8bc65cfc1e6cea..1fd809c1be2fd692c294c7036fa1581f7e266c3f 100644 (file)
@@ -5,7 +5,7 @@ import {
   MActorFollowActorsDefault,
   MActorFollowActorsDefaultSubscription,
   MActorFull,
-  MChannelActorAccountDefault,
+  MChannelAccountDefault,
   MComment,
   MCommentOwnerVideoReply,
   MUserDefault,
@@ -53,7 +53,7 @@ declare module 'express' {
 
       videoStreamingPlaylist?: MStreamingPlaylist
 
-      videoChannel?: MChannelActorAccountDefault
+      videoChannel?: MChannelAccountDefault
 
       videoPlaylistFull?: MVideoPlaylistFull
       videoPlaylistSummary?: MVideoPlaylistFullSummary
index 6d1771de8c39c0654453bb24f3eaa4bd6aa8ce1b..d20d97aa8f774e07a497414ffa759a3073ca36ab 100644 (file)
@@ -2,10 +2,16 @@ import { AccountBlocklistModel } from '../../../models/account/account-blocklist
 import { PickWith } from '../../utils'
 import { MAccountDefault } from './account'
 
+type Use<K extends keyof AccountBlocklistModel, M> = PickWith<AccountBlocklistModel, K, M>
+
+// ############################################################################
+
 export type MAccountBlocklist = Omit<AccountBlocklistModel, 'ByAccount' | 'BlockedAccount'>
 
+// ############################################################################
+
 export type MAccountBlocklistId = Pick<AccountBlocklistModel, 'id'>
 
 export type MAccountBlocklistAccounts = MAccountBlocklist &
-  PickWith<AccountBlocklistModel, 'ByAccount', MAccountDefault> &
-  PickWith<AccountBlocklistModel, 'BlockedAccount', MAccountDefault>
+  Use<'ByAccount', MAccountDefault> &
+  Use<'BlockedAccount', MAccountDefault>
index f3646d5102dcb54e64fb73ce6b80b6bf4e7814a0..9a8784e6bcd56b233d8ad61ead208c1bd0624d49 100644 (file)
@@ -5,7 +5,8 @@ import {
   MActorAPI,
   MActorAudience,
   MActorDefault,
-  MActorDefaultLight, MActorId,
+  MActorDefaultLight,
+  MActorId,
   MActorServer,
   MActorSummary,
   MActorUrl
@@ -14,43 +15,63 @@ import { PickWith } from '../../utils'
 import { MAccountBlocklistId } from './account-blocklist'
 import { MChannelDefault } from '@server/typings/models'
 
-export type MAccountId = Pick<AccountModel, 'id'>
-export type MAccountIdActor = MAccountId &
-  PickWith<AccountModel, 'Actor', MActorAccountChannelId>
-export type MAccountIdActorId = MAccountId &
-  PickWith<AccountModel, 'Actor', MActorId>
+type Use<K extends keyof AccountModel, M> = PickWith<AccountModel, K, M>
+
+// ############################################################################
 
 export type MAccount = Omit<AccountModel, 'Actor' | 'User' | 'Application' | 'VideoChannels' | 'VideoPlaylists' |
   'VideoComments' | 'BlockedAccounts'>
 
+// ############################################################################
+
+// Only some attributes
+export type MAccountId = Pick<MAccount, 'id'>
+export type MAccountUserId = Pick<MAccount, 'userId'>
+
+// Only some Actor attributes
+export type MAccountUrl = Use<'Actor', MActorUrl>
+export type MAccountAudience = Use<'Actor', MActorAudience>
+
+export type MAccountIdActor = MAccountId &
+  Use<'Actor', MActorAccountChannelId>
+
+export type MAccountIdActorId = MAccountId &
+  Use<'Actor', MActorId>
+
+// ############################################################################
+
 // Default scope
 export type MAccountDefault = MAccount &
-  PickWith<AccountModel, 'Actor', MActorDefault>
+  Use<'Actor', MActorDefault>
 
-export type MAccountDefaultChannelDefault = MAccountDefault &
-  PickWith<AccountModel, 'VideoChannels', MChannelDefault[]>
+// Default with default association scopes
+export type MAccountDefaultChannelDefault = MAccount &
+  Use<'Actor', MActorDefault> &
+  Use<'VideoChannels', MChannelDefault[]>
 
+// We don't need some actors attributes
 export type MAccountLight = MAccount &
-  PickWith<AccountModel, 'Actor', MActorDefaultLight>
+  Use<'Actor', MActorDefaultLight>
 
-export type MAccountUserId = Pick<MAccount, 'userId'>
+// ############################################################################
 
+// Full actor
 export type MAccountActor = MAccount &
-  PickWith<AccountModel, 'Actor', MActor>
-export type MAccountServer = MAccountActor &
-  PickWith<AccountModel, 'Actor', MActorServer>
+  Use<'Actor', MActor>
 
-export type MAccountActorDefault = MAccount &
-  PickWith<AccountModel, 'Actor', MActorDefault>
+// Full actor with server
+export type MAccountServer = MAccount &
+  Use<'Actor', MActorServer>
 
-export type MAccountSummary = Pick<MAccount, 'id' | 'name'> &
-  PickWith<AccountModel, 'Actor', MActorSummary>
+// ############################################################################
 
-export type MAccountBlocks = MAccountSummary &
-  PickWith<AccountModel, 'BlockedAccounts', MAccountBlocklistId[]>
+// For API
+
+export type MAccountSummary = Pick<MAccount, 'id' | 'name'> &
+  Use<'Actor', MActorSummary>
 
-export type MAccountAPI = MAccountDefault &
-  PickWith<AccountModel, 'Actor', MActorAPI>
+export type MAccountSummaryBlocks = MAccountSummary &
+  Use<'BlockedAccounts', MAccountBlocklistId[]>
 
-export type MAccountUrl = PickWith<AccountModel, 'Actor', MActorUrl>
-export type MAccountAudience = PickWith<AccountModel, 'Actor', MActorAudience>
+export type MAccountAPI = MAccount &
+  Use<'Actor', MActorAPI>
index 96c53d857102aac1b38063219e82b0dab95cab39..87050ac63ff7d7d148bf2425cd35d2ebc8d99427 100644 (file)
@@ -1,27 +1,55 @@
 import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
-import { MActor, MActorAccountChannel, MActorChannel, MActorChannelAccount, MActorDefault, MActorHost, MActorUsername } from './actor'
+import {
+  MActor,
+  MActorAccount,
+  MActorAccountChannel,
+  MActorChannel,
+  MActorChannelAccountActor,
+  MActorDefault,
+  MActorHost,
+  MActorUsername
+} from './actor'
 import { PickWith } from '../../utils'
+import { ActorModel } from '@server/models/activitypub/actor'
+
+type Use<K extends keyof ActorFollowModel, M> = PickWith<ActorFollowModel, K, M>
+
+// ############################################################################
 
 export type MActorFollow = Omit<ActorFollowModel, 'ActorFollower' | 'ActorFollowing'>
 
+// ############################################################################
+
+export type MActorFollowFollowingHost = MActorFollow &
+  Use<'ActorFollowing', MActorUsername & MActorHost>
+
+// ############################################################################
+
+// With actors or actors default
+
 export type MActorFollowActors = MActorFollow &
-  PickWith<ActorFollowModel, 'ActorFollower', MActor> &
-  PickWith<ActorFollowModel, 'ActorFollowing', MActor>
+  Use<'ActorFollower', MActor> &
+  Use<'ActorFollowing', MActor>
 
 export type MActorFollowActorsDefault = MActorFollow &
-  PickWith<ActorFollowModel, 'ActorFollower', MActorDefault> &
-  PickWith<ActorFollowModel, 'ActorFollowing', MActorDefault>
-
-export type MActorFollowActorsDefaultSubscription = MActorFollow &
-  PickWith<ActorFollowModel, 'ActorFollower', MActorDefault> &
-  PickWith<ActorFollowModel, 'ActorFollowing', MActorDefault & MActorChannel>
+  Use<'ActorFollower', MActorDefault> &
+  Use<'ActorFollowing', MActorDefault>
 
 export type MActorFollowFull = MActorFollow &
-  PickWith<ActorFollowModel, 'ActorFollower', MActorAccountChannel> &
-  PickWith<ActorFollowModel, 'ActorFollowing', MActorAccountChannel>
+  Use<'ActorFollower', MActorAccountChannel> &
+  Use<'ActorFollowing', MActorAccountChannel>
 
-export type MActorFollowFollowingHost = MActorFollow &
-  PickWith<ActorFollowModel, 'ActorFollowing', MActorUsername & MActorHost>
+// ############################################################################
+
+// For subscriptions
+
+export type MActorFollowActorsDefaultSubscription = MActorFollow &
+  Use<'ActorFollower', MActorDefault> &
+  Use<'ActorFollowing', MActorDefault & MActorChannel>
+
+export type MActorFollowFollowingFullFollowerAccount = MActorFollow &
+  Use<'ActorFollower', MActorAccount> &
+  Use<'ActorFollowing', MActorAccountChannel>
 
 export type MActorFollowSubscriptions = MActorFollow &
-  PickWith<ActorFollowModel, 'ActorFollowing', MActorChannelAccount>
+  Use<'ActorFollowing', MActorChannelAccountActor>
index f3e752a98afe286985bd5feb5fa3f485bd49f6d5..7d99a433b34ed26751571fbd4033329dbceefbec 100644 (file)
 import { ActorModel } from '../../../models/activitypub/actor'
 import { PickWith } from '../../utils'
-import { MAccount, MAccountActorDefault, MAccountId, MAccountIdActor } from './account'
-import { MServerHost, MServerHostBlocks, MServer } from '../server'
+import { MAccount, MAccountDefault, MAccountId, MAccountIdActor } from './account'
+import { MServer, MServerHost, MServerHostBlocks } from '../server'
 import { MAvatar } from './avatar'
-import { MChannel, MChannelAccountActor, MChannelActorAccountDefault, MChannelId, MChannelIdActor } from '../video'
+import { MChannel, MChannelAccountActor, MChannelAccountDefault, MChannelId, MChannelIdActor } from '../video'
+
+type Use<K extends keyof ActorModel, M> = PickWith<ActorModel, K, M>
+
+// ############################################################################
 
 export type MActor = Omit<ActorModel, 'Account' | 'VideoChannel' | 'ActorFollowing' | 'Avatar' | 'ActorFollowers' | 'Server'>
 
+// ############################################################################
+
 export type MActorUrl = Pick<MActor, 'url'>
 export type MActorId = Pick<MActor, 'id'>
 export type MActorUsername = Pick<MActor, 'preferredUsername'>
-export type MActorHost = PickWith<ActorModel, 'Server', MServerHost>
 
 export type MActorFollowersUrl = Pick<MActor, 'followersUrl'>
 export type MActorAudience = MActorUrl & MActorFollowersUrl
+export type MActorFollowerException = Pick<ActorModel, 'sharedInboxUrl' | 'inboxUrl'>
+export type MActorSignature = MActorAccountChannelId
 
 export type MActorLight = Omit<MActor, 'privateKey' | 'privateKey'>
 
+// ############################################################################
+
+// Some association attributes
+
+export type MActorHost = Use<'Server', MServerHost>
+
 export type MActorDefaultLight = MActorLight &
-  MActorHost &
-  PickWith<ActorModel, 'Avatar', MAvatar>
+  Use<'Server', MServerHost> &
+  Use<'Avatar', MAvatar>
 
 export type MActorAccountId = MActor &
-  PickWith<ActorModel, 'Account', MAccountId>
+  Use<'Account', MAccountId>
 export type MActorAccountIdActor = MActor &
-  PickWith<ActorModel, 'Account', MAccountIdActor>
+  Use<'Account', MAccountIdActor>
 
 export type MActorChannelId = MActor &
-  PickWith<ActorModel, 'VideoChannel', MChannelId>
+  Use<'VideoChannel', MChannelId>
 export type MActorChannelIdActor = MActor &
-  PickWith<ActorModel, 'VideoChannel', MChannelIdActor>
+  Use<'VideoChannel', MChannelIdActor>
 
 export type MActorAccountChannelId = MActorAccountId & MActorChannelId
 export type MActorAccountChannelIdActor = MActorAccountIdActor & MActorChannelIdActor
 
+// ############################################################################
+
+// Include raw account/channel/server
+
 export type MActorAccount = MActor &
-  PickWith<ActorModel, 'Account', MAccount>
+  Use<'Account', MAccount>
 
 export type MActorChannel = MActor &
-  PickWith<ActorModel, 'VideoChannel', MChannel>
+  Use<'VideoChannel', MChannel>
 
 export type MActorAccountChannel = MActorAccount & MActorChannel
 
-export type MActorChannelAccount = MActor &
-  PickWith<ActorModel, 'VideoChannel', MChannelAccountActor>
-
 export type MActorServer = MActor &
-  PickWith<ActorModel, 'Server', MServer>
+  Use<'Server', MServer>
 
-export type MActorDefault = MActorServer &
-  PickWith<ActorModel, 'Avatar', MAvatar>
+// ############################################################################
 
-export type MActorFull = MActorDefault &
-  PickWith<ActorModel, 'Account', MAccount> &
-  PickWith<ActorModel, 'VideoChannel', MChannelAccountActor>
+// Complex actor associations
 
-export type MActorFullActor = MActorDefault &
-  PickWith<ActorModel, 'Account', MAccountActorDefault> &
-  PickWith<ActorModel, 'VideoChannel', MChannelActorAccountDefault>
+export type MActorDefault = MActor &
+  Use<'Server', MServer> &
+  Use<'Avatar', MAvatar>
 
-export type MActorSummary = Pick<MActor, 'id' | 'preferredUsername' | 'url' | 'serverId' | 'avatarId'> &
-  MActorHost &
-  PickWith<ActorModel, 'Avatar', MAvatar>
+// Actor with channel that is associated to an account and its actor
+// Actor -> VideoChannel -> Account -> Actor
+export type MActorChannelAccountActor = MActor &
+  Use<'VideoChannel', MChannelAccountActor>
 
-export type MActorSummaryBlocks = Omit<MActorSummary, 'Server'> &
-  PickWith<ActorModel, 'Server', MServerHostBlocks>
+export type MActorFull = MActor &
+  Use<'Server', MServer> &
+  Use<'Avatar', MAvatar> &
+  Use<'Account', MAccount> &
+  Use<'VideoChannel', MChannelAccountActor>
 
-export type MActorFollowerException = Pick<ActorModel, 'sharedInboxUrl' | 'inboxUrl'>
+// Same than ActorFull, but the account and the channel have their actor
+export type MActorFullActor = MActor &
+  Use<'Server', MServer> &
+  Use<'Avatar', MAvatar> &
+  Use<'Account', MAccountDefault> &
+  Use<'VideoChannel', MChannelAccountDefault>
+
+// ############################################################################
+
+// API
+
+export type MActorSummary = Pick<MActor, 'id' | 'preferredUsername' | 'url' | 'serverId' | 'avatarId'> &
+  Use<'Server', MServerHost> &
+  Use<'Avatar', MAvatar>
+
+export type MActorSummaryBlocks = MActorSummary &
+  Use<'Server', MServerHostBlocks>
 
 export type MActorAPI = Omit<MActorDefault, 'publicKey' | 'privateKey' | 'inboxUrl' | 'outboxUrl' | 'sharedInboxUrl' |
   'followersUrl' | 'followingUrl' | 'url' | 'createdAt' | 'updatedAt'>
-
-export type MActorSignature = MActorAccountChannelId
index 39e82e4a8c8a76347e29b8c97382a72594d4dad6..78b4948ce85f263f84f1fed28f4002fcfd5f7c88 100644 (file)
@@ -1,4 +1,5 @@
 export * from './account'
+export * from './oauth'
 export * from './server'
 export * from './user'
 export * from './video'
diff --git a/server/typings/models/oauth/index.d.ts b/server/typings/models/oauth/index.d.ts
new file mode 100644 (file)
index 0000000..36b7ea8
--- /dev/null
@@ -0,0 +1,2 @@
+export * from './oauth-client'
+export * from './oauth-token'
index 105ea3df3655592f725d60bd4522e3de1549b8c7..af34129252e9fe97a946f5577f73511046b08420 100644 (file)
@@ -2,8 +2,12 @@ import { OAuthTokenModel } from '@server/models/oauth/oauth-token'
 import { PickWith } from '@server/typings/utils'
 import { MUserAccountUrl } from '@server/typings/models'
 
+type Use<K extends keyof OAuthTokenModel, M> = PickWith<OAuthTokenModel, K, M>
+
+// ############################################################################
+
 export type MOAuthToken = Omit<OAuthTokenModel, 'User' | 'OAuthClients'>
 
 export type MOAuthTokenUser = MOAuthToken &
-  PickWith<OAuthTokenModel, 'User', MUserAccountUrl> &
+  Use<'User', MUserAccountUrl> &
   { user?: MUserAccountUrl }
index 38065f382b442afb18642a9bbfdb8a4087915ef6..0ca00b5c2d69bfd30a89bbab75edc28146f9b608 100644 (file)
@@ -2,8 +2,14 @@ import { ServerBlocklistModel } from '@server/models/server/server-blocklist'
 import { PickWith } from '@server/typings/utils'
 import { MAccountDefault, MServer } from '@server/typings/models'
 
+type Use<K extends keyof ServerBlocklistModel, M> = PickWith<ServerBlocklistModel, K, M>
+
+// ############################################################################
+
 export type MServerBlocklist = Omit<ServerBlocklistModel, 'ByAccount' | 'BlockedServer'>
 
+// ############################################################################
+
 export type MServerBlocklistAccountServer = MServerBlocklist &
-  PickWith<ServerBlocklistModel, 'ByAccount', MAccountDefault> &
-  PickWith<ServerBlocklistModel, 'BlockedServer', MServer>
+  Use<'ByAccount', MAccountDefault> &
+  Use<'BlockedServer', MServer>
index 6be7bf9bb5344a8c2458f29258136013169ec242..c059cff792e154b46c413dda0ab75979b9c60e9d 100644 (file)
@@ -2,9 +2,15 @@ import { ServerModel } from '../../../models/server/server'
 import { PickWith } from '../../utils'
 import { MAccountBlocklistId } from '../account'
 
+type Use<K extends keyof ServerModel, M> = PickWith<ServerModel, K, M>
+
+// ############################################################################
+
 export type MServer = Omit<ServerModel, 'Actors' | 'BlockedByAccounts'>
 
+// ############################################################################
+
 export type MServerHost = Pick<MServer, 'host'>
 
 export type MServerHostBlocks = MServerHost &
-  PickWith<ServerModel, 'BlockedByAccounts', MAccountBlocklistId[]>
+  Use<'BlockedByAccounts', MAccountBlocklistId[]>
index e3353d0b1744a88797f6dd26b12f169bd6c5a823..6657b2128441130471c386600d79158ee9165001 100644 (file)
@@ -1,3 +1,4 @@
 export * from './user'
 export * from './user-notification'
+export * from './user-notification-setting'
 export * from './user-video-history'
index b872c5dc5bd3183acf8ef78a8b446c9cef37d8e0..f9daf5eb29cd674b48c1e9a79ec7111af3933349 100644 (file)
@@ -12,6 +12,10 @@ import { VideoBlacklistModel } from '../../../models/video/video-blacklist'
 import { VideoImportModel } from '../../../models/video/video-import'
 import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
 
+type Use<K extends keyof UserNotificationModel, M> = PickWith<UserNotificationModel, K, M>
+
+// ############################################################################
+
 export namespace UserNotificationIncludes {
   export type VideoInclude = Pick<VideoModel, 'id' | 'uuid' | 'name'>
   export type VideoIncludeChannel = VideoInclude &
@@ -56,14 +60,18 @@ export namespace UserNotificationIncludes {
     PickWith<ActorFollowModel, 'ActorFollowing', ActorFollowing>
 }
 
-export type UserNotificationModelOnly = Omit<UserNotificationModel, 'User' | 'Video' | 'Comment' | 'VideoAbuse' | 'VideoBlacklist' |
+// ############################################################################
+
+export type MUserNotification = Omit<UserNotificationModel, 'User' | 'Video' | 'Comment' | 'VideoAbuse' | 'VideoBlacklist' |
   'VideoImport' | 'Account' | 'ActorFollow'>
 
-export type UserNotificationModelForApi = UserNotificationModelOnly &
-  PickWith<UserNotificationModel, 'Video', UserNotificationIncludes.VideoIncludeChannel> &
-  PickWith<UserNotificationModel, 'Comment', UserNotificationIncludes.VideoCommentInclude> &
-  PickWith<UserNotificationModel, 'VideoAbuse', UserNotificationIncludes.VideoAbuseInclude> &
-  PickWith<UserNotificationModel, 'VideoBlacklist', UserNotificationIncludes.VideoBlacklistInclude> &
-  PickWith<UserNotificationModel, 'VideoImport', UserNotificationIncludes.VideoImportInclude> &
-  PickWith<UserNotificationModel, 'ActorFollow', UserNotificationIncludes.ActorFollowInclude> &
-  PickWith<UserNotificationModel, 'Account', UserNotificationIncludes.AccountIncludeActor>
+// ############################################################################
+
+export type UserNotificationModelForApi = MUserNotification &
+  Use<'Video', UserNotificationIncludes.VideoIncludeChannel> &
+  Use<'Comment', UserNotificationIncludes.VideoCommentInclude> &
+  Use<'VideoAbuse', UserNotificationIncludes.VideoAbuseInclude> &
+  Use<'VideoBlacklist', UserNotificationIncludes.VideoBlacklistInclude> &
+  Use<'VideoImport', UserNotificationIncludes.VideoImportInclude> &
+  Use<'ActorFollow', UserNotificationIncludes.ActorFollowInclude> &
+  Use<'Account', UserNotificationIncludes.AccountIncludeActor>
index b91eed8d91c4de556044a832c525756093c9c206..466cde33b890bf41525eeffe67190bf3fe37f4f1 100644 (file)
@@ -3,30 +3,49 @@ import { PickWith } from '../../utils'
 import { MAccount, MAccountDefault, MAccountDefaultChannelDefault, MAccountId, MAccountIdActorId, MAccountUrl } from '../account'
 import { MNotificationSetting } from './user-notification-setting'
 
+type Use<K extends keyof UserModel, M> = PickWith<UserModel, K, M>
+
+// ############################################################################
+
 export type MUser = Omit<UserModel, 'Account' | 'NotificationSetting' | 'VideoImports' | 'OAuthTokens'>
 
+// ############################################################################
+
 export type MUserId = Pick<UserModel, 'id'>
 
-export type MUserWithNotificationSetting = MUser &
-  PickWith<UserModel, 'NotificationSetting', MNotificationSetting>
+// ############################################################################
 
-export type MUserAccountDefault = MUser &
-  PickWith<UserModel, 'Account', MAccountDefault>
+// With account
+
+export type MUserAccountId = MUser &
+  Use<'Account', MAccountId>
+
+export type MUserAccountUrl = MUser &
+  Use<'Account', MAccountUrl & MAccountIdActorId>
 
 export type MUserAccount = MUser &
-  PickWith<UserModel, 'Account', MAccount>
+  Use<'Account', MAccount>
 
-export type MUserAccountId = MUser &
-  PickWith<UserModel, 'Account', MAccountId>
+export type MUserAccountDefault = MUser &
+  Use<'Account', MAccountDefault>
 
-export type MUserNotifSettingAccount = MUserWithNotificationSetting & MUserAccount
+// With channel
 
-export type MUserDefault = MUser &
-  MUserWithNotificationSetting &
-  MUserAccountDefault
+export type MUserNotifSettingChannelDefault = MUser &
+  Use<'NotificationSetting', MNotificationSetting> &
+  Use<'Account', MAccountDefaultChannelDefault>
 
-export type MUserChannel = MUserWithNotificationSetting &
-  PickWith<UserModel, 'Account', MAccountDefaultChannelDefault>
+// With notification settings
 
-export type MUserAccountUrl = MUser &
-  PickWith<UserModel, 'Account', MAccountUrl & MAccountIdActorId>
+export type MUserWithNotificationSetting = MUser &
+  Use<'NotificationSetting', MNotificationSetting>
+
+export type MUserNotifSettingAccount = MUser &
+  Use<'NotificationSetting', MNotificationSetting> &
+  Use<'Account', MAccount>
+
+// Default scope
+
+export type MUserDefault = MUser &
+  Use<'NotificationSetting', MNotificationSetting> &
+  Use<'Account', MAccountDefault>
index 528e9d274184e01e6506079f7b03b0a59ee42eff..bd69c8a4b273e73c52a1910bd4cf0ebfc3587d37 100644 (file)
@@ -5,10 +5,14 @@ export * from './video'
 export * from './video-abuse'
 export * from './video-blacklist'
 export * from './video-caption'
+export * from './video-change-ownership'
 export * from './video-channels'
 export * from './video-comment'
 export * from './video-file'
+export * from './video-import'
 export * from './video-playlist'
+export * from './video-playlist-element'
+export * from './video-rate'
 export * from './video-redundancy'
 export * from './video-share'
 export * from './video-streaming-playlist'
index 1667ae55a4128a16090e224b36a5d90a11557c86..0474cac5b46d6bb69d75d88659b244630a27180c 100644 (file)
@@ -3,13 +3,21 @@ import { PickWith } from '../../utils'
 import { MVideo } from './video'
 import { MAccountDefault } from '../account'
 
+type Use<K extends keyof VideoAbuseModel, M> = PickWith<VideoAbuseModel, K, M>
+
+// ############################################################################
+
 export type MVideoAbuse = Omit<VideoAbuseModel, 'Account' | 'Video' | 'toActivityPubObject'>
 
+// ############################################################################
+
 export type MVideoAbuseId = Pick<VideoAbuseModel, 'id'>
 
 export type MVideoAbuseVideo = MVideoAbuse &
   Pick<VideoAbuseModel, 'toActivityPubObject'> &
-  PickWith<VideoAbuseModel, 'Video', MVideo>
+  Use<'Video', MVideo>
 
-export type MVideoAbuseAccountVideo = MVideoAbuseVideo &
-  PickWith<VideoAbuseModel, 'Account', MAccountDefault>
+export type MVideoAbuseAccountVideo = MVideoAbuse &
+  Pick<VideoAbuseModel, 'toActivityPubObject'> &
+  Use<'Video', MVideo> &
+  Use<'Account', MAccountDefault>
index 9242b357dd4729e7bbf8aa408b762326df26e11f..cc539f95cff4b21007f084aa4ff8af826aa9623b 100644 (file)
@@ -2,10 +2,16 @@ import { VideoBlacklistModel } from '../../../models/video/video-blacklist'
 import { PickWith } from '@server/typings/utils'
 import { MVideo } from '@server/typings/models'
 
+type Use<K extends keyof VideoBlacklistModel, M> = PickWith<VideoBlacklistModel, K, M>
+
+// ############################################################################
+
 export type MVideoBlacklist = Omit<VideoBlacklistModel, 'Video'>
 
 export type MVideoBlacklistLight = Pick<MVideoBlacklist, 'id' | 'reason' | 'unfederated'>
 export type MVideoBlacklistUnfederated = Pick<MVideoBlacklist, 'unfederated'>
 
+// ############################################################################
+
 export type MVideoBlacklistVideo = MVideoBlacklist &
-  PickWith<VideoBlacklistModel, 'Video', MVideo>
+  Use<'Video', MVideo>
index 16d8b739271b6a021458e4dd867b8d4bc223ad85..fe0e664c2a7ea2247cb60210f50e2b37c12c4d7e 100644 (file)
@@ -2,9 +2,15 @@ import { VideoCaptionModel } from '../../../models/video/video-caption'
 import { PickWith } from '@server/typings/utils'
 import { VideoModel } from '@server/models/video/video'
 
+type Use<K extends keyof VideoCaptionModel, M> = PickWith<VideoCaptionModel, K, M>
+
+// ############################################################################
+
 export type MVideoCaption = Omit<VideoCaptionModel, 'Video'>
 
+// ############################################################################
+
 export type MVideoCaptionLanguage = Pick<MVideoCaption, 'language'>
 
 export type MVideoCaptionVideo = MVideoCaption &
-  PickWith<VideoCaptionModel, 'Video', Pick<VideoModel, 'id' | 'remote' | 'uuid'>>
+  Use<'Video', Pick<VideoModel, 'id' | 'remote' | 'uuid'>>
index 718515e2de66e40ae986b211591777b544c9d00b..0410115c6b22189c630964fece6f930bbfab76a2 100644 (file)
@@ -2,9 +2,13 @@ import { VideoChangeOwnershipModel } from '@server/models/video/video-change-own
 import { PickWith } from '@server/typings/utils'
 import { MAccountDefault, MVideoWithFileThumbnail } from '@server/typings/models'
 
+type Use<K extends keyof VideoChangeOwnershipModel, M> = PickWith<VideoChangeOwnershipModel, K, M>
+
+// ############################################################################
+
 export type MVideoChangeOwnership = Omit<VideoChangeOwnershipModel, 'Initiator' | 'NextOwner' | 'Video'>
 
 export type MVideoChangeOwnershipFull = MVideoChangeOwnership &
-  PickWith<VideoChangeOwnershipModel, 'Initiator', MAccountDefault> &
-  PickWith<VideoChangeOwnershipModel, 'NextOwner', MAccountDefault> &
-  PickWith<VideoChangeOwnershipModel, 'Video', MVideoWithFileThumbnail>
+  Use<'Initiator', MAccountDefault> &
+  Use<'NextOwner', MAccountDefault> &
+  Use<'Video', MVideoWithFileThumbnail>
index e10bd68426f8dfd2ce07fa4196efb6285c07dd32..b6506ed9f6bf83c438332c178a7701f377964e42 100644 (file)
@@ -1,70 +1,97 @@
-import { FunctionProperties, PickWith } from '../../utils'
+import { PickWith } from '../../utils'
 import { VideoChannelModel } from '../../../models/video/video-channel'
 import {
   MAccountActor,
   MAccountAPI,
-  MAccountBlocks,
   MAccountDefault,
   MAccountLight,
+  MAccountSummaryBlocks,
   MAccountUserId,
   MActor,
   MActorAccountChannelId,
   MActorAPI,
   MActorDefault,
-  MActorDefaultLight, MActorLight,
+  MActorDefaultLight,
+  MActorLight,
   MActorSummary
 } from '../account'
 import { MVideo } from './video'
 
-export type MChannelId = FunctionProperties<VideoChannelModel>
-export type MChannelIdActor = MChannelId &
-  PickWith<VideoChannelModel, 'Actor', MActorAccountChannelId>
+type Use<K extends keyof VideoChannelModel, M> = PickWith<VideoChannelModel, K, M>
+
+// ############################################################################
 
 export type MChannel = Omit<VideoChannelModel, 'Actor' | 'Account' | 'Videos' | 'VideoPlaylists'>
 
+// ############################################################################
+
+export type MChannelId = Pick<MChannel, 'id'>
+
+// ############################################################################
+
+export type MChannelIdActor = MChannelId &
+  Use<'Actor', MActorAccountChannelId>
+
 export type MChannelUserId = Pick<MChannel, 'accountId'> &
-  PickWith<VideoChannelModel, 'Account', MAccountUserId>
+  Use<'Account', MAccountUserId>
+
+export type MChannelActor = MChannel &
+  Use<'Actor', MActor>
 
 // Default scope
 export type MChannelDefault = MChannel &
-  PickWith<VideoChannelModel, 'Actor', MActorDefault>
+  Use<'Actor', MActorDefault>
+
+// ############################################################################
+
+// Not all association attributes
 
 export type MChannelLight = MChannel &
-  PickWith<VideoChannelModel, 'Actor', MActorDefaultLight>
+  Use<'Actor', MActorDefaultLight>
 
-export type MChannelAccountLight = MChannel &
-  PickWith<VideoChannelModel, 'Actor', MActorDefaultLight> &
-  PickWith<VideoChannelModel, 'Account', MAccountLight>
+export type MChannelActorLight = MChannel &
+  Use<'Actor', MActorLight>
 
-export type MChannelSummary = Pick<MChannel, 'id' | 'name' | 'description' | 'actorId'> &
-  PickWith<VideoChannelModel, 'Actor', MActorSummary>
+export type MChannelAccountLight = MChannel &
+  Use<'Actor', MActorDefaultLight> &
+  Use<'Account', MAccountLight>
 
-export type MChannelSummaryAccount = MChannelSummary &
-  PickWith<VideoChannelModel, 'Account', MAccountBlocks>
+// ############################################################################
 
-export type MChannelAPI = MChannel &
-  PickWith<VideoChannelModel, 'Actor', MActorAPI> &
-  PickWith<VideoChannelModel, 'Account', MAccountAPI>
+// Account associations
 
 export type MChannelAccountActor = MChannel &
-  PickWith<VideoChannelModel, 'Account', MAccountActor>
-export type MChannelAccountDefault = MChannelActor &
-  PickWith<VideoChannelModel, 'Account', MAccountDefault>
+  Use<'Account', MAccountActor>
+
+export type MChannelAccountDefault = MChannel &
+  Use<'Actor', MActorDefault> &
+  Use<'Account', MAccountDefault>
 
+export type MChannelActorAccountActor = MChannel &
+  Use<'Account', MAccountActor> &
+  Use<'Actor', MActor>
+
+// ############################################################################
+
+// Videos  associations
 export type MChannelVideos = MChannel &
-  PickWith<VideoChannelModel, 'Videos', MVideo[]>
+  Use<'Videos', MVideo[]>
 
-export type MChannelActor = MChannel &
-  PickWith<VideoChannelModel, 'Actor', MActor>
-export type MChannelActorLight = MChannel &
-  PickWith<VideoChannelModel, 'Actor', MActorLight>
-export type MChannelActorDefault = MChannel &
-  PickWith<VideoChannelModel, 'Actor', MActorDefault>
+export type MChannelActorAccountDefaultVideos = MChannel &
+  Use<'Actor', MActorDefault> &
+  Use<'Account', MAccountDefault> &
+  Use<'Videos', MVideo[]>
+
+// ############################################################################
+
+// For API
 
-export type MChannelActorAccountActor = MChannelAccountActor & MChannelActor
+export type MChannelSummary = Pick<MChannel, 'id' | 'name' | 'description' | 'actorId'> &
+  Use<'Actor', MActorSummary>
 
-export type MChannelActorAccountDefault = MChannel &
-  PickWith<VideoChannelModel, 'Actor', MActorDefault> &
-  PickWith<VideoChannelModel, 'Account', MAccountDefault>
+export type MChannelSummaryAccount = MChannelSummary &
+  Use<'Account', MAccountSummaryBlocks>
 
-export type MChannelActorAccountDefaultVideos = MChannelActorAccountDefault & MChannelVideos
+export type MChannelAPI = MChannel &
+  Use<'Actor', MActorAPI> &
+  Use<'Account', MAccountAPI>
index 675613804ee2c9e534f1aec76715c664c1c1acd2..187461213e7d7fd0cdbdedfa65ab74a25a961afe 100644 (file)
@@ -1,29 +1,43 @@
 import { VideoCommentModel } from '../../../models/video/video-comment'
 import { PickWith } from '../../utils'
 import { MAccountDefault } from '../account'
-import { MVideoAccountDefault, MVideoAccountLight, MVideoFeed, MVideoIdUrl } from './video'
+import { MVideoAccountLight, MVideoFeed, MVideoIdUrl } from './video'
+
+type Use<K extends keyof VideoCommentModel, M> = PickWith<VideoCommentModel, K, M>
+
+// ############################################################################
 
 export type MComment = Omit<VideoCommentModel, 'OriginVideoComment' | 'InReplyToVideoComment' | 'Video' | 'Account'>
 export type MCommentId = Pick<MComment, 'id'>
 
-export type MCommentAPI = MComment & { totalReplies: number }
+// ############################################################################
 
 export type MCommentOwner = MComment &
-  PickWith<VideoCommentModel, 'Account', MAccountDefault>
+  Use<'Account', MAccountDefault>
 
 export type MCommentVideo = MComment &
-  PickWith<VideoCommentModel, 'Video', MVideoAccountLight>
+  Use<'Video', MVideoAccountLight>
 
 export type MCommentReply = MComment &
-  PickWith<VideoCommentModel, 'InReplyToVideoComment', MComment>
+  Use<'InReplyToVideoComment', MComment>
+
+export type MCommentOwnerVideo = MComment &
+  Use<'Account', MAccountDefault> &
+  Use<'Video', MVideoAccountLight>
 
-export type MCommentOwnerReply = MCommentOwner & MCommentReply
-export type MCommentOwnerVideo = MCommentOwner & MCommentVideo
-export type MCommentReplyVideo = MCommentReply & MCommentVideo
-export type MCommentOwnerVideoReply = MCommentOwnerVideo & MCommentReply
+export type MCommentOwnerVideoReply = MComment &
+  Use<'Account', MAccountDefault> &
+  Use<'Video', MVideoAccountLight> &
+  Use<'InReplyToVideoComment', MComment>
 
-export type MCommentOwnerReplyVideoLight = MCommentOwnerReply &
-  PickWith<VideoCommentModel, 'Video', MVideoIdUrl>
+export type MCommentOwnerReplyVideoLight = MComment &
+  Use<'Account', MAccountDefault> &
+  Use<'InReplyToVideoComment', MComment> &
+  Use<'Video', MVideoIdUrl>
 
 export type MCommentOwnerVideoFeed = MCommentOwner &
-  PickWith<VideoCommentModel, 'Video', MVideoFeed>
+  Use<'Video', MVideoFeed>
+
+// ############################################################################
+
+export type MCommentAPI = MComment & { totalReplies: number }
index afa659d1fbf4ed40116aea5b2959dafabf713577..484351a8d03fdf4d4aaeaeb57104acc38038bf95 100644 (file)
@@ -3,13 +3,17 @@ import { PickWith, PickWithOpt } from '../../utils'
 import { MVideo, MVideoUUID } from './video'
 import { MVideoRedundancyFileUrl } from './video-redundancy'
 
+type Use<K extends keyof VideoFileModel, M> = PickWith<VideoFileModel, K, M>
+
+// ############################################################################
+
 export type MVideoFile = Omit<VideoFileModel, 'Video' | 'RedundancyVideos'>
 
 export type MVideoFileVideo = MVideoFile &
-  PickWith<VideoFileModel, 'Video', MVideo>
+  Use<'Video', MVideo>
 
 export type MVideoFileVideoUUID = MVideoFile &
-  PickWith<VideoFileModel, 'Video', MVideoUUID>
+  Use<'Video', MVideoUUID>
 
 export type MVideoFileRedundanciesOpt = MVideoFile &
   PickWithOpt<VideoFileModel, 'RedundancyVideos', MVideoRedundancyFileUrl[]>
index 51be900d6d63e5375698732717fe950534060df5..ada7237134c14502f149ac56660ea7f2f58043a4 100644 (file)
@@ -2,14 +2,23 @@ import { VideoImportModel } from '@server/models/video/video-import'
 import { PickWith } from '@server/typings/utils'
 import { MUser, MVideo, MVideoAccountLight, MVideoTag, MVideoThumbnail, MVideoWithFile } from '@server/typings/models'
 
-export type MVideoImport = Omit<VideoImportModel, 'User' | 'Video'>
+type Use<K extends keyof VideoImportModel, M> = PickWith<VideoImportModel, K, M>
 
-export type MVideoImportDefault = MVideoImport &
-  PickWith<VideoImportModel, 'User', MUser> &
-  PickWith<VideoImportModel, 'Video', MVideoTag & MVideoAccountLight & MVideoThumbnail>
+// ############################################################################
 
-export type MVideoImportDefaultFiles = MVideoImportDefault &
-  PickWith<VideoImportModel, 'Video', MVideoTag & MVideoAccountLight & MVideoThumbnail & MVideoWithFile>
+export type MVideoImport = Omit<VideoImportModel, 'User' | 'Video'>
 
 export type MVideoImportVideo = MVideoImport &
-  PickWith<VideoImportModel, 'Video', MVideo>
+  Use<'Video', MVideo>
+
+// ############################################################################
+
+type VideoAssociation = MVideoTag & MVideoAccountLight & MVideoThumbnail
+
+export type MVideoImportDefault = MVideoImport &
+  Use<'User', MUser> &
+  Use<'Video', VideoAssociation>
+
+export type MVideoImportDefaultFiles = MVideoImport &
+  Use<'User', MUser> &
+  Use<'Video', VideoAssociation & MVideoWithFile>
index d1b8a18a05f8861c4efb2e02d11c7a34dc7dc1dc..5a039d7b191a6889d2c03c9bd4b2463e588ca73a 100644 (file)
@@ -2,14 +2,27 @@ import { VideoPlaylistElementModel } from '@server/models/video/video-playlist-e
 import { PickWith } from '@server/typings/utils'
 import { MVideoPlaylistPrivacy, MVideoThumbnail, MVideoUrl } from '@server/typings/models'
 
+type Use<K extends keyof VideoPlaylistElementModel, M> = PickWith<VideoPlaylistElementModel, K, M>
+
+// ############################################################################
+
 export type MVideoPlaylistElement = Omit<VideoPlaylistElementModel, 'VideoPlaylist' | 'Video'>
+
+// ############################################################################
+
 export type MVideoPlaylistElementId = Pick<MVideoPlaylistElement, 'id'>
 
 export type MVideoPlaylistElementLight = Pick<MVideoPlaylistElement, 'id' | 'videoId' | 'startTimestamp' | 'stopTimestamp'>
 
+// ############################################################################
+
 export type MVideoPlaylistVideoThumbnail = MVideoPlaylistElement &
-  PickWith<VideoPlaylistElementModel, 'Video', MVideoThumbnail>
+  Use<'Video', MVideoThumbnail>
+
+// ############################################################################
+
+// For API
 
 export type MVideoPlaylistAP = MVideoPlaylistElement &
-  PickWith<VideoPlaylistElementModel, 'Video', MVideoUrl> &
-  PickWith<VideoPlaylistElementModel, 'VideoPlaylist', MVideoPlaylistPrivacy>
+  Use<'Video', MVideoUrl> &
+  Use<'VideoPlaylist', MVideoPlaylistPrivacy>
index 825b3391c9b653b1128bcabe0e274203c62495af..6338184057da8f19039337d0d5259050679d55d2 100644 (file)
@@ -5,38 +5,76 @@ import { MThumbnail } from './thumbnail'
 import { MChannelDefault, MChannelSummary } from './video-channels'
 import { MVideoPlaylistElementLight } from '@server/typings/models/video/video-playlist-element'
 
+type Use<K extends keyof VideoPlaylistModel, M> = PickWith<VideoPlaylistModel, K, M>
+
+// ############################################################################
+
 export type MVideoPlaylist = Omit<VideoPlaylistModel, 'OwnerAccount' | 'VideoChannel' | 'VideoPlaylistElements' | 'Thumbnail'>
+
+// ############################################################################
+
 export type MVideoPlaylistId = Pick<MVideoPlaylist, 'id'>
 export type MVideoPlaylistPrivacy = Pick<MVideoPlaylist, 'privacy'>
+export type MVideoPlaylistUUID = Pick<MVideoPlaylist, 'uuid'>
+export type MVideoPlaylistVideosLength = MVideoPlaylist & { videosLength: number }
+
+// ############################################################################
+
+// With elements
 
 export type MVideoPlaylistWithElements = MVideoPlaylist &
-  PickWith<VideoPlaylistModel, 'VideoPlaylistElements', MVideoPlaylistElementLight[]>
-export type MVideoPlaylistIdWithElements = MVideoPlaylistId & MVideoPlaylistWithElements
+  Use<'VideoPlaylistElements', MVideoPlaylistElementLight[]>
 
-export type MVideoPlaylistUUID = Pick<MVideoPlaylist, 'uuid'>
+export type MVideoPlaylistIdWithElements = MVideoPlaylistId &
+  Use<'VideoPlaylistElements', MVideoPlaylistElementLight[]>
+
+// ############################################################################
+
+// With account
 
 export type MVideoPlaylistOwner = MVideoPlaylist &
-  PickWith<VideoPlaylistModel, 'OwnerAccount', MAccount>
+  Use<'OwnerAccount', MAccount>
 
 export type MVideoPlaylistOwnerDefault = MVideoPlaylist &
-  PickWith<VideoPlaylistModel, 'OwnerAccount', MAccountDefault>
+  Use<'OwnerAccount', MAccountDefault>
+
+// ############################################################################
+
+// With thumbnail
 
 export type MVideoPlaylistThumbnail = MVideoPlaylist &
-  PickWith<VideoPlaylistModel, 'Thumbnail', MThumbnail>
+  Use<'Thumbnail', MThumbnail>
 
-export type MVideoPlaylistAccountThumbnail = MVideoPlaylistOwnerDefault &
-  PickWith<VideoPlaylistModel, 'Thumbnail', MThumbnail>
+export type MVideoPlaylistAccountThumbnail = MVideoPlaylist &
+  Use<'OwnerAccount', MAccountDefault> &
+  Use<'Thumbnail', MThumbnail>
 
-export type MVideoPlaylistAccountChannelSummary = MVideoPlaylist &
-  PickWith<VideoPlaylistModel, 'OwnerAccount', MAccountSummary> &
-  PickWith<VideoPlaylistModel, 'VideoChannel', MChannelSummary>
+// ############################################################################
+
+// With channel
 
 export type MVideoPlaylistAccountChannelDefault = MVideoPlaylist &
-  PickWith<VideoPlaylistModel, 'OwnerAccount', MAccountDefault> &
-  PickWith<VideoPlaylistModel, 'VideoChannel', MChannelDefault>
+  Use<'OwnerAccount', MAccountDefault> &
+  Use<'VideoChannel', MChannelDefault>
 
-export type MVideoPlaylistVideosLength = MVideoPlaylist & { videosLength: number }
+// ############################################################################
 
-export type MVideoPlaylistFullSummary = MVideoPlaylistAccountChannelSummary & MVideoPlaylistThumbnail
+// With all associations
+
+export type MVideoPlaylistFull = MVideoPlaylist &
+  Use<'OwnerAccount', MAccountDefault> &
+  Use<'VideoChannel', MChannelDefault> &
+  Use<'Thumbnail', MThumbnail>
+
+// ############################################################################
+
+// For API
+
+export type MVideoPlaylistAccountChannelSummary = MVideoPlaylist &
+  Use<'OwnerAccount', MAccountSummary> &
+  Use<'VideoChannel', MChannelSummary>
 
-export type MVideoPlaylistFull = MVideoPlaylist & MVideoPlaylistThumbnail & MVideoPlaylistAccountChannelDefault
+export type MVideoPlaylistFullSummary = MVideoPlaylist &
+  Use<'Thumbnail', MThumbnail> &
+  Use<'OwnerAccount', MAccountSummary> &
+  Use<'VideoChannel', MChannelSummary>
index 6eefe636212dfd3ba26e5a5a8fb25c23ceeefc0f..fc932999354c06385dcaabbb369e212c14628538 100644 (file)
@@ -2,11 +2,15 @@ import { AccountVideoRateModel } from '@server/models/account/account-video-rate
 import { PickWith } from '@server/typings/utils'
 import { MAccountAudience, MAccountUrl, MVideo } from '..'
 
+type Use<K extends keyof AccountVideoRateModel, M> = PickWith<AccountVideoRateModel, K, M>
+
+// ############################################################################
+
 export type MAccountVideoRate = Omit<AccountVideoRateModel, 'Video' | 'Account'>
 
 export type MAccountVideoRateAccountUrl = MAccountVideoRate &
-  PickWith<AccountVideoRateModel, 'Account', MAccountUrl>
+  Use<'Account', MAccountUrl>
 
 export type MAccountVideoRateAccountVideo = MAccountVideoRate &
-  PickWith<AccountVideoRateModel, 'Account', MAccountAudience> &
-  PickWith<AccountVideoRateModel, 'Video', MVideo>
+  Use<'Account', MAccountAudience> &
+  Use<'Video', MVideo>
index ec61bfb68d5b15ee99554f00a78f8fdae4862b12..c25eb9c09bb690618484b33fa0f1ca0cbe111f1d 100644 (file)
@@ -2,17 +2,25 @@ import { VideoRedundancyModel } from '../../../models/redundancy/video-redundanc
 import { PickWith } from '@server/typings/utils'
 import { MStreamingPlaylistVideo, MVideoFile, MVideoFileVideo } from '@server/typings/models'
 
+type Use<K extends keyof VideoRedundancyModel, M> = PickWith<VideoRedundancyModel, K, M>
+
+// ############################################################################
+
 export type MVideoRedundancy = Omit<VideoRedundancyModel, 'VideoFile' | 'VideoStreamingPlaylist' | 'Actor'>
 
 export type MVideoRedundancyFileUrl = Pick<MVideoRedundancy, 'fileUrl'>
 
+// ############################################################################
+
 export type MVideoRedundancyFile = MVideoRedundancy &
-  PickWith<VideoRedundancyModel, 'VideoFile', MVideoFile>
+  Use<'VideoFile', MVideoFile>
 
 export type MVideoRedundancyFileVideo = MVideoRedundancy &
-  PickWith<VideoRedundancyModel, 'VideoFile', MVideoFileVideo>
+  Use<'VideoFile', MVideoFileVideo>
 
 export type MVideoRedundancyStreamingPlaylistVideo = MVideoRedundancy &
-  PickWith<VideoRedundancyModel, 'VideoStreamingPlaylist', MStreamingPlaylistVideo>
+  Use<'VideoStreamingPlaylist', MStreamingPlaylistVideo>
 
-export type MVideoRedundancyVideo = MVideoRedundancyFileVideo | MVideoRedundancyStreamingPlaylistVideo
+export type MVideoRedundancyVideo = MVideoRedundancy &
+  Use<'VideoFile', MVideoFileVideo> &
+  Use<'VideoStreamingPlaylist', MStreamingPlaylistVideo>
index 7e8cb8b6197d17ee47a1e697fafc5266a89be80e..a7a90beeb7e0266eea368e001c3b593632a0091c 100644 (file)
@@ -3,10 +3,15 @@ import { PickWith } from '../../utils'
 import { MActorDefault } from '../account'
 import { MVideo } from './video'
 
+type Use<K extends keyof VideoShareModel, M> = PickWith<VideoShareModel, K, M>
+
+// ############################################################################
+
 export type MVideoShare = Omit<VideoShareModel, 'Actor' | 'Video'>
 
 export type MVideoShareActor = MVideoShare &
-  PickWith<VideoShareModel, 'Actor', MActorDefault>
+  Use<'Actor', MActorDefault>
 
-export type MVideoShareFull = MVideoShareActor &
-  PickWith<VideoShareModel, 'Video', MVideo>
+export type MVideoShareFull = MVideoShare &
+  Use<'Actor', MActorDefault> &
+  Use<'Video', MVideo>
index 5b631077142b4e3b3b71e9035eb35416d271b788..f1b3438b65ea7fc7a4a8c4d2b9e0c42886395569 100644 (file)
@@ -3,10 +3,14 @@ import { PickWith } from '../../utils'
 import { MVideoRedundancyFileUrl } from './video-redundancy'
 import { MVideo } from '@server/typings/models'
 
+type Use<K extends keyof VideoStreamingPlaylistModel, M> = PickWith<VideoStreamingPlaylistModel, K, M>
+
+// ############################################################################
+
 export type MStreamingPlaylist = Omit<VideoStreamingPlaylistModel, 'Video' | 'RedundancyVideos'>
 
 export type MStreamingPlaylistVideo = MStreamingPlaylist &
-  PickWith<VideoStreamingPlaylistModel, 'Video', MVideo>
+  Use<'Video', MVideo>
 
 export type MStreamingPlaylistRedundancies = MStreamingPlaylist &
-  PickWith<VideoStreamingPlaylistModel, 'RedundancyVideos', MVideoRedundancyFileUrl[]>
+  Use<'RedundancyVideos', MVideoRedundancyFileUrl[]>
index 0ffd0c30222ffd1dde5bc28e951bfd2f15966d80..914eb7f577d011440cc7d33b18a090da7b34b8ba 100644 (file)
@@ -1,6 +1,6 @@
 import { VideoModel } from '../../../models/video/video'
 import { PickWith, PickWithOpt } from '../../utils'
-import { MChannelAccountLight, MChannelActor, MChannelActorAccountDefault, MChannelUserId } from './video-channels'
+import { MChannelAccountDefault, MChannelAccountLight, MChannelActor, MChannelUserId } from './video-channels'
 import { MTag } from './tag'
 import { MVideoCaptionLanguage } from './video-caption'
 import { MStreamingPlaylist, MStreamingPlaylistRedundancies } from './video-streaming-playlist'
@@ -10,10 +10,16 @@ import { MVideoBlacklistLight, MVideoBlacklistUnfederated } from './video-blackl
 import { MScheduleVideoUpdate } from './schedule-video-update'
 import { MUserVideoHistoryTime } from '../user/user-video-history'
 
+type Use<K extends keyof VideoModel, M> = PickWith<VideoModel, K, M>
+
+// ############################################################################
+
 export type MVideo = Omit<VideoModel, 'VideoChannel' | 'Tags' | 'Thumbnails' | 'VideoPlaylistElements' | 'VideoAbuses' |
   'VideoFiles' | 'VideoStreamingPlaylists' | 'VideoShares' | 'AccountVideoRates' | 'VideoComments' | 'VideoViews' | 'UserVideoHistories' |
   'ScheduleVideoUpdate' | 'VideoBlacklist' | 'VideoImport' | 'VideoCaptions'>
 
+// ############################################################################
+
 export type MVideoId = Pick<MVideo, 'id'>
 export type MVideoUrl = Pick<MVideo, 'url'>
 export type MVideoUUID = Pick<MVideo, 'uuid'>
@@ -21,83 +27,120 @@ export type MVideoUUID = Pick<MVideo, 'uuid'>
 export type MVideoIdUrl = MVideoId & MVideoUrl
 export type MVideoFeed = Pick<MVideo, 'name' | 'uuid'>
 
+// ############################################################################
+
+// Video raw associations: schedules, video files, tags, thumbnails, captions, streaming playlists
+
+// "With" to not confuse with the VideoFile model
 export type MVideoWithFile = MVideo &
-  PickWith<VideoModel, 'VideoFiles', MVideoFile[]>
+  Use<'VideoFiles', MVideoFile[]>
 
 export type MVideoThumbnail = MVideo &
-  PickWith<VideoModel, 'Thumbnails', MThumbnail[]>
-export type MVideoIdThumbnail = MVideoThumbnail & MVideoId
+  Use<'Thumbnails', MThumbnail[]>
+
+export type MVideoIdThumbnail = MVideoId &
+  Use<'Thumbnails', MThumbnail[]>
+
+export type MVideoWithFileThumbnail = MVideo &
+  Use<'VideoFiles', MVideoFile[]> &
+  Use<'Thumbnails', MThumbnail[]>
 
 export type MVideoTag = MVideo &
-  PickWith<VideoModel, 'Tags', MTag[]>
+  Use<'Tags', MTag[]>
 
 export type MVideoWithSchedule = MVideo &
   PickWithOpt<VideoModel, 'ScheduleVideoUpdate', MScheduleVideoUpdate>
 
-export type MVideoWithFileThumbnail = MVideoWithFile & MVideoThumbnail
+export type MVideoWithCaptions = MVideo &
+  Use<'VideoCaptions', MVideoCaptionLanguage[]>
 
-export type MVideoUser = MVideo &
-  PickWith<VideoModel, 'VideoChannel', MChannelUserId>
+export type MVideoWithStreamingPlaylist = MVideo &
+  Use<'VideoStreamingPlaylists', MStreamingPlaylist[]>
 
-export type MVideoWithCaptions = MVideo &
-  PickWith<VideoModel, 'VideoCaptions', MVideoCaptionLanguage[]>
+// ############################################################################
+
+// Associations with not all their attributes
+
+export type MVideoUserHistory = MVideo &
+  Use<'UserVideoHistories', MUserVideoHistoryTime[]>
 
 export type MVideoWithBlacklistLight = MVideo &
-  PickWith<VideoModel, 'VideoBlacklist', MVideoBlacklistLight>
+  Use<'VideoBlacklist', MVideoBlacklistLight>
 
 export type MVideoAccountLight = MVideo &
-  PickWith<VideoModel, 'VideoChannel', MChannelAccountLight>
+  Use<'VideoChannel', MChannelAccountLight>
 
-export type MVideoWithRights = MVideoWithBlacklistLight & MVideoThumbnail & MVideoUser
+export type MVideoWithRights = MVideo &
+  Use<'VideoBlacklist', MVideoBlacklistLight> &
+  Use<'Thumbnails', MThumbnail[]> &
+  Use<'VideoChannel', MChannelUserId>
 
-export type MVideoWithStreamingPlaylist = MVideo &
-  PickWith<VideoModel, 'VideoStreamingPlaylists', MStreamingPlaylist[]>
+// ############################################################################
 
-export type MVideoWithAllFiles = MVideoWithFileThumbnail & MVideoWithStreamingPlaylist
+// All files with some additional associations
 
-export type MVideoAccountAllFiles = MVideoWithAllFiles & MVideoAccountLight & MVideoWithBlacklistLight
-export type MVideoAccountAllFilesCaptions = MVideoAccountAllFiles & MVideoWithCaptions
+export type MVideoWithAllFiles = MVideo &
+  Use<'VideoFiles', MVideoFile[]> &
+  Use<'Thumbnails', MThumbnail[]> &
+  Use<'VideoStreamingPlaylists', MStreamingPlaylist[]>
 
-export type MVideoUserHistory = MVideo &
-  PickWith<VideoModel, 'UserVideoHistories', MUserVideoHistoryTime[]>
+export type MVideoAccountLightBlacklistAllFiles = MVideo &
+  Use<'VideoFiles', MVideoFile[]> &
+  Use<'Thumbnails', MThumbnail[]> &
+  Use<'VideoStreamingPlaylists', MStreamingPlaylist[]> &
+  Use<'VideoChannel', MChannelAccountLight> &
+  Use<'VideoBlacklist', MVideoBlacklistLight>
 
-export type MVideoWithBlacklistThumbnailScheduled = MVideoWithSchedule & MVideoWithBlacklistLight & MVideoWithFileThumbnail
+// ############################################################################
+
+// With account
 
 export type MVideoAccountDefault = MVideo &
-  PickWith<VideoModel, 'VideoChannel', MChannelActorAccountDefault>
+  Use<'VideoChannel', MChannelAccountDefault>
 
-export type MVideoThumbnailAccountDefault = MVideoThumbnail &
-  PickWith<VideoModel, 'VideoChannel', MChannelActorAccountDefault>
+export type MVideoThumbnailAccountDefault = MVideo &
+  Use<'Thumbnails', MThumbnail[]> &
+  Use<'VideoChannel', MChannelAccountDefault>
 
 export type MVideoWithChannelActor = MVideo &
-  PickWith<VideoModel, 'VideoChannel', MChannelActor>
-
-export type MVideoFullLight = MVideoThumbnail &
-  MVideoWithBlacklistLight &
-  MVideoTag &
-  MVideoAccountLight &
-  MVideoUserHistory &
-  MVideoWithFile &
-  MVideoWithSchedule &
-  MVideoWithStreamingPlaylist &
-  MVideoUserHistory
+  Use<'VideoChannel', MChannelActor>
+
+export type MVideoFullLight = MVideo &
+  Use<'Thumbnails', MThumbnail[]> &
+  Use<'VideoBlacklist', MVideoBlacklistLight> &
+  Use<'Tags', MTag[]> &
+  Use<'VideoChannel', MChannelAccountLight> &
+  Use<'UserVideoHistories', MUserVideoHistoryTime[]> &
+  Use<'VideoFiles', MVideoFile[]> &
+  Use<'ScheduleVideoUpdate', MScheduleVideoUpdate> &
+  Use<'VideoStreamingPlaylists', MStreamingPlaylist[]>
+
+// ############################################################################
+
+// API
 
 export type MVideoAP = MVideo &
-  MVideoTag &
-  MVideoAccountLight &
-  MVideoWithStreamingPlaylist &
-  MVideoWithCaptions &
-  PickWith<VideoModel, 'VideoBlacklist', MVideoBlacklistUnfederated> &
-  PickWith<VideoModel, 'VideoFiles', MVideoFileRedundanciesOpt[]>
+  Use<'Tags', MTag[]> &
+  Use<'VideoChannel', MChannelAccountLight> &
+  Use<'VideoStreamingPlaylists', MStreamingPlaylist[]> &
+  Use<'VideoCaptions', MVideoCaptionLanguage[]> &
+  Use<'VideoBlacklist', MVideoBlacklistUnfederated> &
+  Use<'VideoFiles', MVideoFileRedundanciesOpt[]>
 
 export type MVideoAPWithoutCaption = Omit<MVideoAP, 'VideoCaptions'>
 
 export type MVideoDetails = MVideo &
-  MVideoWithBlacklistLight &
-  MVideoTag &
-  MVideoAccountLight &
-  MVideoWithSchedule &
-  MVideoThumbnail &
-  MVideoUserHistory &
-  PickWith<VideoModel, 'VideoStreamingPlaylists', MStreamingPlaylistRedundancies[]> &
-  PickWith<VideoModel, 'VideoFiles', MVideoFileRedundanciesOpt[]>
+  Use<'VideoBlacklist', MVideoBlacklistLight> &
+  Use<'Tags', MTag[]> &
+  Use<'VideoChannel', MChannelAccountLight> &
+  Use<'ScheduleVideoUpdate', MScheduleVideoUpdate> &
+  Use<'Thumbnails', MThumbnail[]> &
+  Use<'UserVideoHistories', MUserVideoHistoryTime[]> &
+  Use<'VideoStreamingPlaylists', MStreamingPlaylistRedundancies[]> &
+  Use<'VideoFiles', MVideoFileRedundanciesOpt[]>
+
+export type MVideoForUser = MVideo &
+  Use<'VideoChannel', MChannelAccountDefault> &
+  Use<'ScheduleVideoUpdate', MScheduleVideoUpdate> &
+  Use<'VideoBlacklist', MVideoBlacklistLight> &
+  Use<'Thumbnails', MThumbnail[]>