aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/controllers/api/users/index.ts2
-rw-r--r--server/controllers/api/users/me.ts11
-rw-r--r--server/controllers/api/video-channel.ts4
-rw-r--r--server/controllers/api/videos/import.ts10
-rw-r--r--server/helpers/captions-utils.ts4
-rw-r--r--server/lib/activitypub/actor.ts4
-rw-r--r--server/lib/user.ts19
-rw-r--r--server/lib/video-channel.ts10
-rw-r--r--server/models/account/account-blocklist.ts4
-rw-r--r--server/models/account/account-video-rate.ts9
-rw-r--r--server/models/account/account.ts8
-rw-r--r--server/models/account/user-notification-setting.ts3
-rw-r--r--server/models/account/user.ts12
-rw-r--r--server/models/activitypub/actor-follow.ts3
-rw-r--r--server/models/activitypub/actor.ts32
-rw-r--r--server/models/avatar/avatar.ts3
-rw-r--r--server/models/server/plugin.ts4
-rw-r--r--server/models/server/server-blocklist.ts4
-rw-r--r--server/models/server/server.ts4
-rw-r--r--server/models/video/schedule-video-update.ts3
-rw-r--r--server/models/video/video-abuse.ts4
-rw-r--r--server/models/video/video-blacklist.ts4
-rw-r--r--server/models/video/video-caption.ts10
-rw-r--r--server/models/video/video-change-ownership.ts4
-rw-r--r--server/models/video/video-channel.ts30
-rw-r--r--server/models/video/video-comment.ts3
-rw-r--r--server/models/video/video-format-utils.ts6
-rw-r--r--server/models/video/video-import.ts4
-rw-r--r--server/models/video/video-playlist-element.ts19
-rw-r--r--server/models/video/video-playlist.ts3
-rw-r--r--server/models/video/video.ts11
-rw-r--r--server/typings/models/account/account-blocklist.ts10
-rw-r--r--server/typings/models/account/account.ts21
-rw-r--r--server/typings/models/account/actor-follow.ts16
-rw-r--r--server/typings/models/account/actor.ts23
-rw-r--r--server/typings/models/account/avatar.ts8
-rw-r--r--server/typings/models/server/plugin.ts7
-rw-r--r--server/typings/models/server/server-blocklist.ts10
-rw-r--r--server/typings/models/server/server.ts10
-rw-r--r--server/typings/models/user/user-notification-setting.ts6
-rw-r--r--server/typings/models/user/user.ts25
-rw-r--r--server/typings/models/video/schedule-video-update.ts6
-rw-r--r--server/typings/models/video/video-abuse.ts10
-rw-r--r--server/typings/models/video/video-blacklist.ts9
-rw-r--r--server/typings/models/video/video-caption.ts14
-rw-r--r--server/typings/models/video/video-change-ownership.ts11
-rw-r--r--server/typings/models/video/video-channels.ts27
-rw-r--r--server/typings/models/video/video-comment.ts10
-rw-r--r--server/typings/models/video/video-import.ts11
-rw-r--r--server/typings/models/video/video-playlist-element.ts11
-rw-r--r--server/typings/models/video/video-playlist.ts14
-rw-r--r--server/typings/models/video/video-rate.ts9
-rw-r--r--server/typings/models/video/video.ts27
-rw-r--r--server/typings/utils.ts2
54 files changed, 401 insertions, 147 deletions
diff --git a/server/controllers/api/users/index.ts b/server/controllers/api/users/index.ts
index e6b678f3a..27351c1a9 100644
--- a/server/controllers/api/users/index.ts
+++ b/server/controllers/api/users/index.ts
@@ -196,7 +196,7 @@ async function createUser (req: express.Request, res: express.Response) {
196 videoQuota: body.videoQuota, 196 videoQuota: body.videoQuota,
197 videoQuotaDaily: body.videoQuotaDaily, 197 videoQuotaDaily: body.videoQuotaDaily,
198 adminFlags: body.adminFlags || UserAdminFlag.NONE 198 adminFlags: body.adminFlags || UserAdminFlag.NONE
199 }) 199 }) as MUser
200 200
201 const { user, account } = await createUserAccountAndChannelAndPlaylist({ userToCreate: userToCreate }) 201 const { user, account } = await createUserAccountAndChannelAndPlaylist({ userToCreate: userToCreate })
202 202
diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts
index af054f620..78e1e7fa3 100644
--- a/server/controllers/api/users/me.ts
+++ b/server/controllers/api/users/me.ts
@@ -23,15 +23,12 @@ import { createReqFiles } from '../../../helpers/express-utils'
23import { UserVideoQuota } from '../../../../shared/models/users/user-video-quota.model' 23import { UserVideoQuota } from '../../../../shared/models/users/user-video-quota.model'
24import { updateAvatarValidator } from '../../../middlewares/validators/avatar' 24import { updateAvatarValidator } from '../../../middlewares/validators/avatar'
25import { updateActorAvatarFile } from '../../../lib/avatar' 25import { updateActorAvatarFile } from '../../../lib/avatar'
26import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '../../../helpers/audit-logger'
27import { VideoImportModel } from '../../../models/video/video-import' 26import { VideoImportModel } from '../../../models/video/video-import'
28import { AccountModel } from '../../../models/account/account' 27import { AccountModel } from '../../../models/account/account'
29import { CONFIG } from '../../../initializers/config' 28import { CONFIG } from '../../../initializers/config'
30import { sequelizeTypescript } from '../../../initializers/database' 29import { sequelizeTypescript } from '../../../initializers/database'
31import { sendVerifyUserEmail } from '../../../lib/user' 30import { sendVerifyUserEmail } from '../../../lib/user'
32 31
33const auditLogger = auditLoggerFactory('users-me')
34
35const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.TMP_DIR }) 32const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.TMP_DIR })
36 33
37const meRouter = express.Router() 34const meRouter = express.Router()
@@ -165,8 +162,6 @@ async function deleteMe (req: express.Request, res: express.Response) {
165 162
166 await user.destroy() 163 await user.destroy()
167 164
168 auditLogger.delete(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON({})))
169
170 return res.sendStatus(204) 165 return res.sendStatus(204)
171} 166}
172 167
@@ -175,7 +170,6 @@ async function updateMe (req: express.Request, res: express.Response) {
175 let sendVerificationEmail = false 170 let sendVerificationEmail = false
176 171
177 const user = res.locals.oauth.token.user 172 const user = res.locals.oauth.token.user
178 const oldUserAuditView = new UserAuditView(user.toFormattedJSON({}))
179 173
180 if (body.password !== undefined) user.password = body.password 174 if (body.password !== undefined) user.password = body.password
181 if (body.nsfwPolicy !== undefined) user.nsfwPolicy = body.nsfwPolicy 175 if (body.nsfwPolicy !== undefined) user.nsfwPolicy = body.nsfwPolicy
@@ -204,8 +198,6 @@ async function updateMe (req: express.Request, res: express.Response) {
204 await userAccount.save({ transaction: t }) 198 await userAccount.save({ transaction: t })
205 199
206 await sendUpdateActor(userAccount, t) 200 await sendUpdateActor(userAccount, t)
207
208 auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON({})), oldUserAuditView)
209 }) 201 })
210 202
211 if (sendVerificationEmail === true) { 203 if (sendVerificationEmail === true) {
@@ -218,13 +210,10 @@ async function updateMe (req: express.Request, res: express.Response) {
218async function updateMyAvatar (req: express.Request, res: express.Response) { 210async function updateMyAvatar (req: express.Request, res: express.Response) {
219 const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ] 211 const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ]
220 const user = res.locals.oauth.token.user 212 const user = res.locals.oauth.token.user
221 const oldUserAuditView = new UserAuditView(user.toFormattedJSON({}))
222 213
223 const userAccount = await AccountModel.load(user.Account.id) 214 const userAccount = await AccountModel.load(user.Account.id)
224 215
225 const avatar = await updateActorAvatarFile(avatarPhysicalFile, userAccount) 216 const avatar = await updateActorAvatarFile(avatarPhysicalFile, userAccount)
226 217
227 auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON({})), oldUserAuditView)
228
229 return res.json({ avatar: avatar.toFormattedJSON() }) 218 return res.json({ avatar: avatar.toFormattedJSON() })
230} 219}
diff --git a/server/controllers/api/video-channel.ts b/server/controllers/api/video-channel.ts
index 2b6184a83..d4ca7a0af 100644
--- a/server/controllers/api/video-channel.ts
+++ b/server/controllers/api/video-channel.ts
@@ -19,7 +19,7 @@ import { VideoChannelModel } from '../../models/video/video-channel'
19import { videoChannelsNameWithHostValidator, videosSortValidator } from '../../middlewares/validators' 19import { videoChannelsNameWithHostValidator, videosSortValidator } from '../../middlewares/validators'
20import { sendUpdateActor } from '../../lib/activitypub/send' 20import { sendUpdateActor } from '../../lib/activitypub/send'
21import { VideoChannelCreate, VideoChannelUpdate } from '../../../shared' 21import { VideoChannelCreate, VideoChannelUpdate } from '../../../shared'
22import { createVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel' 22import { createLocalVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel'
23import { buildNSFWFilter, createReqFiles, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils' 23import { buildNSFWFilter, createReqFiles, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils'
24import { setAsyncActorKeys } from '../../lib/activitypub' 24import { setAsyncActorKeys } from '../../lib/activitypub'
25import { AccountModel } from '../../models/account/account' 25import { AccountModel } from '../../models/account/account'
@@ -139,7 +139,7 @@ async function addVideoChannel (req: express.Request, res: express.Response) {
139 const videoChannelCreated = await sequelizeTypescript.transaction(async t => { 139 const videoChannelCreated = await sequelizeTypescript.transaction(async t => {
140 const account = await AccountModel.load(res.locals.oauth.token.User.Account.id, t) 140 const account = await AccountModel.load(res.locals.oauth.token.User.Account.id, t)
141 141
142 return createVideoChannel(videoChannelInfo, account, t) 142 return createLocalVideoChannel(videoChannelInfo, account, t)
143 }) 143 })
144 144
145 setAsyncActorKeys(videoChannelCreated.Actor) 145 setAsyncActorKeys(videoChannelCreated.Actor)
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts
index e7adcc35a..8879f3442 100644
--- a/server/controllers/api/videos/import.ts
+++ b/server/controllers/api/videos/import.ts
@@ -1,6 +1,5 @@
1import * as express from 'express' 1import * as express from 'express'
2import * as magnetUtil from 'magnet-uri' 2import * as magnetUtil from 'magnet-uri'
3import 'multer'
4import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger' 3import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger'
5import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoImportAddValidator } from '../../../middlewares' 4import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoImportAddValidator } from '../../../middlewares'
6import { MIMETYPES } from '../../../initializers/constants' 5import { MIMETYPES } from '../../../initializers/constants'
@@ -28,11 +27,12 @@ import {
28 MChannelAccountDefault, 27 MChannelAccountDefault,
29 MThumbnail, 28 MThumbnail,
30 MUser, 29 MUser,
30 MVideoAccountDefault,
31 MVideoTag, 31 MVideoTag,
32 MVideoThumbnailAccountDefault, 32 MVideoThumbnailAccountDefault,
33 MVideoWithBlacklistLight 33 MVideoWithBlacklistLight
34} from '@server/typings/models' 34} from '@server/typings/models'
35import { MVideoImport, MVideoImportVideo } from '@server/typings/models/video/video-import' 35import { MVideoImport, MVideoImportFormattable } from '@server/typings/models/video/video-import'
36 36
37const auditLogger = auditLoggerFactory('video-imports') 37const auditLogger = auditLoggerFactory('video-imports')
38const videoImportsRouter = express.Router() 38const videoImportsRouter = express.Router()
@@ -238,14 +238,14 @@ function insertIntoDB (parameters: {
238 tags: string[], 238 tags: string[],
239 videoImportAttributes: Partial<MVideoImport>, 239 videoImportAttributes: Partial<MVideoImport>,
240 user: MUser 240 user: MUser
241}): Bluebird<MVideoImportVideo> { 241}): Bluebird<MVideoImportFormattable> {
242 const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters 242 const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters
243 243
244 return sequelizeTypescript.transaction(async t => { 244 return sequelizeTypescript.transaction(async t => {
245 const sequelizeOptions = { transaction: t } 245 const sequelizeOptions = { transaction: t }
246 246
247 // Save video object in database 247 // Save video object in database
248 const videoCreated = await video.save(sequelizeOptions) as (MVideoThumbnailAccountDefault & MVideoWithBlacklistLight & MVideoTag) 248 const videoCreated = await video.save(sequelizeOptions) as (MVideoAccountDefault & MVideoWithBlacklistLight & MVideoTag)
249 videoCreated.VideoChannel = videoChannel 249 videoCreated.VideoChannel = videoChannel
250 250
251 if (thumbnailModel) await videoCreated.addAndSaveThumbnail(thumbnailModel, t) 251 if (thumbnailModel) await videoCreated.addAndSaveThumbnail(thumbnailModel, t)
@@ -274,7 +274,7 @@ function insertIntoDB (parameters: {
274 const videoImport = await VideoImportModel.create( 274 const videoImport = await VideoImportModel.create(
275 Object.assign({ videoId: videoCreated.id }, videoImportAttributes), 275 Object.assign({ videoId: videoCreated.id }, videoImportAttributes),
276 sequelizeOptions 276 sequelizeOptions
277 ) as MVideoImportVideo 277 ) as MVideoImportFormattable
278 videoImport.Video = videoCreated 278 videoImport.Video = videoCreated
279 279
280 return videoImport 280 return videoImport
diff --git a/server/helpers/captions-utils.ts b/server/helpers/captions-utils.ts
index 4f29058e5..2830ae017 100644
--- a/server/helpers/captions-utils.ts
+++ b/server/helpers/captions-utils.ts
@@ -2,9 +2,9 @@ import { join } from 'path'
2import { CONFIG } from '../initializers/config' 2import { CONFIG } from '../initializers/config'
3import * as srt2vtt from 'srt-to-vtt' 3import * as srt2vtt from 'srt-to-vtt'
4import { createReadStream, createWriteStream, move, remove } from 'fs-extra' 4import { createReadStream, createWriteStream, move, remove } from 'fs-extra'
5import { MVideoCaption } from '@server/typings/models' 5import { MVideoCaptionFormattable } from '@server/typings/models'
6 6
7async function moveAndProcessCaptionFile (physicalFile: { filename: string, path: string }, videoCaption: MVideoCaption) { 7async function moveAndProcessCaptionFile (physicalFile: { filename: string, path: string }, videoCaption: MVideoCaptionFormattable) {
8 const videoCaptionsDir = CONFIG.STORAGE.CAPTIONS_DIR 8 const videoCaptionsDir = CONFIG.STORAGE.CAPTIONS_DIR
9 const destination = join(videoCaptionsDir, videoCaption.getCaptionName()) 9 const destination = join(videoCaptionsDir, videoCaption.getCaptionName())
10 10
diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts
index 5201bdeef..13b73077e 100644
--- a/server/lib/activitypub/actor.ts
+++ b/server/lib/activitypub/actor.ts
@@ -38,7 +38,7 @@ import {
38} from '../../typings/models' 38} from '../../typings/models'
39 39
40// Set account keys, this could be long so process after the account creation and do not block the client 40// Set account keys, this could be long so process after the account creation and do not block the client
41function setAsyncActorKeys (actor: MActor) { 41function setAsyncActorKeys <T extends MActor> (actor: T) {
42 return createPrivateAndPublicKeys() 42 return createPrivateAndPublicKeys()
43 .then(({ publicKey, privateKey }) => { 43 .then(({ publicKey, privateKey }) => {
44 actor.publicKey = publicKey 44 actor.publicKey = publicKey
@@ -148,7 +148,7 @@ function buildActorInstance (type: ActivityPubActorType, url: string, preferredU
148 sharedInboxUrl: WEBSERVER.URL + '/inbox', 148 sharedInboxUrl: WEBSERVER.URL + '/inbox',
149 followersUrl: url + '/followers', 149 followersUrl: url + '/followers',
150 followingUrl: url + '/following' 150 followingUrl: url + '/following'
151 }) 151 }) as MActor
152} 152}
153 153
154async function updateActorInstance (actorInstance: ActorModel, attributes: ActivityPubActor) { 154async function updateActorInstance (actorInstance: ActorModel, attributes: ActivityPubActor) {
diff --git a/server/lib/user.ts b/server/lib/user.ts
index 266974cac..d84aff464 100644
--- a/server/lib/user.ts
+++ b/server/lib/user.ts
@@ -2,9 +2,8 @@ import * as uuidv4 from 'uuid/v4'
2import { ActivityPubActorType } from '../../shared/models/activitypub' 2import { ActivityPubActorType } from '../../shared/models/activitypub'
3import { SERVER_ACTOR_NAME, WEBSERVER } from '../initializers/constants' 3import { SERVER_ACTOR_NAME, WEBSERVER } from '../initializers/constants'
4import { AccountModel } from '../models/account/account' 4import { AccountModel } from '../models/account/account'
5import { UserModel } from '../models/account/user'
6import { buildActorInstance, getAccountActivityPubUrl, setAsyncActorKeys } from './activitypub' 5import { buildActorInstance, getAccountActivityPubUrl, setAsyncActorKeys } from './activitypub'
7import { createVideoChannel } from './video-channel' 6import { createLocalVideoChannel } from './video-channel'
8import { ActorModel } from '../models/activitypub/actor' 7import { ActorModel } from '../models/activitypub/actor'
9import { UserNotificationSettingModel } from '../models/account/user-notification-setting' 8import { UserNotificationSettingModel } from '../models/account/user-notification-setting'
10import { UserNotificationSetting, UserNotificationSettingValue } from '../../shared/models/users' 9import { UserNotificationSetting, UserNotificationSettingValue } from '../../shared/models/users'
@@ -13,17 +12,17 @@ import { sequelizeTypescript } from '../initializers/database'
13import { Transaction } from 'sequelize/types' 12import { Transaction } from 'sequelize/types'
14import { Redis } from './redis' 13import { Redis } from './redis'
15import { Emailer } from './emailer' 14import { Emailer } from './emailer'
16import { MAccountActor, MActor, MChannelActor } from '../typings/models' 15import { MAccountDefault, MActorDefault, MChannelActor } from '../typings/models'
17import { MUser, MUserId, MUserNotifSettingAccount } from '../typings/models/user' 16import { MUser, MUserDefault, MUserId } from '../typings/models/user'
18 17
19type ChannelNames = { name: string, displayName: string } 18type ChannelNames = { name: string, displayName: string }
20 19
21async function createUserAccountAndChannelAndPlaylist (parameters: { 20async function createUserAccountAndChannelAndPlaylist (parameters: {
22 userToCreate: UserModel, 21 userToCreate: MUser,
23 userDisplayName?: string, 22 userDisplayName?: string,
24 channelNames?: ChannelNames, 23 channelNames?: ChannelNames,
25 validateUser?: boolean 24 validateUser?: boolean
26}): Promise<{ user: MUserNotifSettingAccount, account: MAccountActor, videoChannel: MChannelActor }> { 25}): Promise<{ user: MUserDefault, account: MAccountDefault, videoChannel: MChannelActor }> {
27 const { userToCreate, userDisplayName, channelNames, validateUser = true } = parameters 26 const { userToCreate, userDisplayName, channelNames, validateUser = true } = parameters
28 27
29 const { user, account, videoChannel } = await sequelizeTypescript.transaction(async t => { 28 const { user, account, videoChannel } = await sequelizeTypescript.transaction(async t => {
@@ -32,7 +31,7 @@ async function createUserAccountAndChannelAndPlaylist (parameters: {
32 validate: validateUser 31 validate: validateUser
33 } 32 }
34 33
35 const userCreated: MUserNotifSettingAccount = await userToCreate.save(userOptions) 34 const userCreated: MUserDefault = await userToCreate.save(userOptions)
36 userCreated.NotificationSetting = await createDefaultUserNotificationSettings(userCreated, t) 35 userCreated.NotificationSetting = await createDefaultUserNotificationSettings(userCreated, t)
37 36
38 const accountCreated = await createLocalAccountWithoutKeys({ 37 const accountCreated = await createLocalAccountWithoutKeys({
@@ -45,7 +44,7 @@ async function createUserAccountAndChannelAndPlaylist (parameters: {
45 userCreated.Account = accountCreated 44 userCreated.Account = accountCreated
46 45
47 const channelAttributes = await buildChannelAttributes(userCreated, channelNames) 46 const channelAttributes = await buildChannelAttributes(userCreated, channelNames)
48 const videoChannel = await createVideoChannel(channelAttributes, accountCreated, t) 47 const videoChannel = await createLocalVideoChannel(channelAttributes, accountCreated, t)
49 48
50 const videoPlaylist = await createWatchLaterPlaylist(accountCreated, t) 49 const videoPlaylist = await createWatchLaterPlaylist(accountCreated, t)
51 50
@@ -75,7 +74,7 @@ async function createLocalAccountWithoutKeys (parameters: {
75 const url = getAccountActivityPubUrl(name) 74 const url = getAccountActivityPubUrl(name)
76 75
77 const actorInstance = buildActorInstance(type, url, name) 76 const actorInstance = buildActorInstance(type, url, name)
78 const actorInstanceCreated: MActor = await actorInstance.save({ transaction: t }) 77 const actorInstanceCreated: MActorDefault = await actorInstance.save({ transaction: t })
79 78
80 const accountInstance = new AccountModel({ 79 const accountInstance = new AccountModel({
81 name: displayName || name, 80 name: displayName || name,
@@ -84,7 +83,7 @@ async function createLocalAccountWithoutKeys (parameters: {
84 actorId: actorInstanceCreated.id 83 actorId: actorInstanceCreated.id
85 }) 84 })
86 85
87 const accountInstanceCreated: MAccountActor = await accountInstance.save({ transaction: t }) 86 const accountInstanceCreated: MAccountDefault = await accountInstance.save({ transaction: t })
88 accountInstanceCreated.Actor = actorInstanceCreated 87 accountInstanceCreated.Actor = actorInstanceCreated
89 88
90 return accountInstanceCreated 89 return accountInstanceCreated
diff --git a/server/lib/video-channel.ts b/server/lib/video-channel.ts
index ee8eb6568..41eab456b 100644
--- a/server/lib/video-channel.ts
+++ b/server/lib/video-channel.ts
@@ -4,12 +4,12 @@ import { VideoChannelCreate } from '../../shared/models'
4import { VideoChannelModel } from '../models/video/video-channel' 4import { VideoChannelModel } from '../models/video/video-channel'
5import { buildActorInstance, federateVideoIfNeeded, getVideoChannelActivityPubUrl } from './activitypub' 5import { buildActorInstance, federateVideoIfNeeded, getVideoChannelActivityPubUrl } from './activitypub'
6import { VideoModel } from '../models/video/video' 6import { VideoModel } from '../models/video/video'
7import { MAccountId, MChannelActor, MChannelId } from '../typings/models' 7import { MAccountId, MChannelDefault, MChannelId } from '../typings/models'
8 8
9type CustomVideoChannelModelAccount <T extends MAccountId> = MChannelActor & 9type CustomVideoChannelModelAccount <T extends MAccountId> = MChannelDefault &
10 { Account?: T } 10 { Account?: T }
11 11
12async function createVideoChannel <T extends MAccountId> ( 12async function createLocalVideoChannel <T extends MAccountId> (
13 videoChannelInfo: VideoChannelCreate, 13 videoChannelInfo: VideoChannelCreate,
14 account: T, 14 account: T,
15 t: Sequelize.Transaction 15 t: Sequelize.Transaction
@@ -31,7 +31,7 @@ async function createVideoChannel <T extends MAccountId> (
31 const videoChannel = new VideoChannelModel(videoChannelData) 31 const videoChannel = new VideoChannelModel(videoChannelData)
32 32
33 const options = { transaction: t } 33 const options = { transaction: t }
34 const videoChannelCreated: CustomVideoChannelModelAccount<T> = await videoChannel.save(options) as MChannelActor 34 const videoChannelCreated: CustomVideoChannelModelAccount<T> = await videoChannel.save(options) as MChannelDefault
35 35
36 // Do not forget to add Account/Actor information to the created video channel 36 // Do not forget to add Account/Actor information to the created video channel
37 videoChannelCreated.Account = account 37 videoChannelCreated.Account = account
@@ -54,6 +54,6 @@ async function federateAllVideosOfChannel (videoChannel: MChannelId) {
54// --------------------------------------------------------------------------- 54// ---------------------------------------------------------------------------
55 55
56export { 56export {
57 createVideoChannel, 57 createLocalVideoChannel,
58 federateAllVideosOfChannel 58 federateAllVideosOfChannel
59} 59}
diff --git a/server/models/account/account-blocklist.ts b/server/models/account/account-blocklist.ts
index bb5371395..8bcaca828 100644
--- a/server/models/account/account-blocklist.ts
+++ b/server/models/account/account-blocklist.ts
@@ -4,7 +4,7 @@ import { getSort } from '../utils'
4import { AccountBlock } from '../../../shared/models/blocklist' 4import { AccountBlock } from '../../../shared/models/blocklist'
5import { Op } from 'sequelize' 5import { Op } from 'sequelize'
6import * as Bluebird from 'bluebird' 6import * as Bluebird from 'bluebird'
7import { MAccountBlocklist, MAccountBlocklistAccounts } from '@server/typings/models' 7import { MAccountBlocklist, MAccountBlocklistAccounts, MAccountBlocklistFormattable } from '@server/typings/models'
8 8
9enum ScopeNames { 9enum ScopeNames {
10 WITH_ACCOUNTS = 'WITH_ACCOUNTS' 10 WITH_ACCOUNTS = 'WITH_ACCOUNTS'
@@ -134,7 +134,7 @@ export class AccountBlocklistModel extends Model<AccountBlocklistModel> {
134 }) 134 })
135 } 135 }
136 136
137 toFormattedJSON (): AccountBlock { 137 toFormattedJSON (this: MAccountBlocklistFormattable): AccountBlock {
138 return { 138 return {
139 byAccount: this.ByAccount.toFormattedJSON(), 139 byAccount: this.ByAccount.toFormattedJSON(),
140 blockedAccount: this.BlockedAccount.toFormattedJSON(), 140 blockedAccount: this.BlockedAccount.toFormattedJSON(),
diff --git a/server/models/account/account-video-rate.ts b/server/models/account/account-video-rate.ts
index 8b62dd05f..a6edbeee8 100644
--- a/server/models/account/account-video-rate.ts
+++ b/server/models/account/account-video-rate.ts
@@ -11,7 +11,12 @@ import { isActivityPubUrlValid } from '../../helpers/custom-validators/activityp
11import { AccountVideoRate } from '../../../shared' 11import { AccountVideoRate } from '../../../shared'
12import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from '../video/video-channel' 12import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from '../video/video-channel'
13import * as Bluebird from 'bluebird' 13import * as Bluebird from 'bluebird'
14import { MAccountVideoRate, MAccountVideoRateAccountUrl, MAccountVideoRateAccountVideo } from '@server/typings/models/video/video-rate' 14import {
15 MAccountVideoRate,
16 MAccountVideoRateAccountUrl,
17 MAccountVideoRateAccountVideo,
18 MAccountVideoRateFormattable
19} from '@server/typings/models/video/video-rate'
15 20
16/* 21/*
17 Account rates per video. 22 Account rates per video.
@@ -248,7 +253,7 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
248 }) 253 })
249 } 254 }
250 255
251 toFormattedJSON (): AccountVideoRate { 256 toFormattedJSON (this: MAccountVideoRateFormattable): AccountVideoRate {
252 return { 257 return {
253 video: this.Video.toFormattedJSON(), 258 video: this.Video.toFormattedJSON(),
254 rating: this.type 259 rating: this.type
diff --git a/server/models/account/account.ts b/server/models/account/account.ts
index 4cc731075..8369738b9 100644
--- a/server/models/account/account.ts
+++ b/server/models/account/account.ts
@@ -32,7 +32,7 @@ import { FindOptions, IncludeOptions, Op, Transaction, WhereOptions } from 'sequ
32import { AccountBlocklistModel } from './account-blocklist' 32import { AccountBlocklistModel } from './account-blocklist'
33import { ServerBlocklistModel } from '../server/server-blocklist' 33import { ServerBlocklistModel } from '../server/server-blocklist'
34import { ActorFollowModel } from '../activitypub/actor-follow' 34import { ActorFollowModel } from '../activitypub/actor-follow'
35import { MAccountActor, MAccountDefault } from '../../typings/models' 35import { MAccountActor, MAccountDefault, MAccountSummaryFormattable, MAccountFormattable } from '../../typings/models'
36import * as Bluebird from 'bluebird' 36import * as Bluebird from 'bluebird'
37 37
38export enum ScopeNames { 38export enum ScopeNames {
@@ -353,7 +353,7 @@ export class AccountModel extends Model<AccountModel> {
353 .findAll(query) 353 .findAll(query)
354 } 354 }
355 355
356 toFormattedJSON (): Account { 356 toFormattedJSON (this: MAccountFormattable): Account {
357 const actor = this.Actor.toFormattedJSON() 357 const actor = this.Actor.toFormattedJSON()
358 const account = { 358 const account = {
359 id: this.id, 359 id: this.id,
@@ -367,8 +367,8 @@ export class AccountModel extends Model<AccountModel> {
367 return Object.assign(actor, account) 367 return Object.assign(actor, account)
368 } 368 }
369 369
370 toFormattedSummaryJSON (): AccountSummary { 370 toFormattedSummaryJSON (this: MAccountSummaryFormattable): AccountSummary {
371 const actor = this.Actor.toFormattedJSON() 371 const actor = this.Actor.toFormattedSummaryJSON()
372 372
373 return { 373 return {
374 id: this.id, 374 id: this.id,
diff --git a/server/models/account/user-notification-setting.ts b/server/models/account/user-notification-setting.ts
index c2fbc6d23..1506295cf 100644
--- a/server/models/account/user-notification-setting.ts
+++ b/server/models/account/user-notification-setting.ts
@@ -17,6 +17,7 @@ import { UserModel } from './user'
17import { isUserNotificationSettingValid } from '../../helpers/custom-validators/user-notifications' 17import { isUserNotificationSettingValid } from '../../helpers/custom-validators/user-notifications'
18import { UserNotificationSetting, UserNotificationSettingValue } from '../../../shared/models/users/user-notification-setting.model' 18import { UserNotificationSetting, UserNotificationSettingValue } from '../../../shared/models/users/user-notification-setting.model'
19import { clearCacheByUserId } from '../../lib/oauth-model' 19import { clearCacheByUserId } from '../../lib/oauth-model'
20import { MNotificationSettingFormattable } from '@server/typings/models'
20 21
21@Table({ 22@Table({
22 tableName: 'userNotificationSetting', 23 tableName: 'userNotificationSetting',
@@ -152,7 +153,7 @@ export class UserNotificationSettingModel extends Model<UserNotificationSettingM
152 return clearCacheByUserId(instance.userId) 153 return clearCacheByUserId(instance.userId)
153 } 154 }
154 155
155 toFormattedJSON (): UserNotificationSetting { 156 toFormattedJSON (this: MNotificationSettingFormattable): UserNotificationSetting {
156 return { 157 return {
157 newCommentOnMyVideo: this.newCommentOnMyVideo, 158 newCommentOnMyVideo: this.newCommentOnMyVideo,
158 newVideoFromSubscription: this.newVideoFromSubscription, 159 newVideoFromSubscription: this.newVideoFromSubscription,
diff --git a/server/models/account/user.ts b/server/models/account/user.ts
index cb54d79af..616dd603c 100644
--- a/server/models/account/user.ts
+++ b/server/models/account/user.ts
@@ -55,7 +55,13 @@ import { UserAdminFlag } from '../../../shared/models/users/user-flag.model'
55import { isThemeNameValid } from '../../helpers/custom-validators/plugins' 55import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
56import { getThemeOrDefault } from '../../lib/plugins/theme-utils' 56import { getThemeOrDefault } from '../../lib/plugins/theme-utils'
57import * as Bluebird from 'bluebird' 57import * as Bluebird from 'bluebird'
58import { MUserNotifSettingChannelDefault, MUserDefault, MUserId, MUserWithNotificationSetting } from '@server/typings/models' 58import {
59 MUserDefault,
60 MUserFormattable,
61 MUserId,
62 MUserNotifSettingChannelDefault,
63 MUserWithNotificationSetting
64} from '@server/typings/models'
59 65
60enum ScopeNames { 66enum ScopeNames {
61 WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL' 67 WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL'
@@ -554,7 +560,9 @@ export class UserModel extends Model<UserModel> {
554 return comparePassword(password, this.password) 560 return comparePassword(password, this.password)
555 } 561 }
556 562
557 toFormattedJSON (parameters: { withAdminFlags?: boolean } = {}): User { 563 toSummaryJSON
564
565 toFormattedJSON (this: MUserFormattable, parameters: { withAdminFlags?: boolean } = {}): User {
558 const videoQuotaUsed = this.get('videoQuotaUsed') 566 const videoQuotaUsed = this.get('videoQuotaUsed')
559 const videoQuotaUsedDaily = this.get('videoQuotaUsedDaily') 567 const videoQuotaUsedDaily = this.get('videoQuotaUsedDaily')
560 568
diff --git a/server/models/activitypub/actor-follow.ts b/server/models/activitypub/actor-follow.ts
index 8ef770cd4..c8b3aae9f 100644
--- a/server/models/activitypub/actor-follow.ts
+++ b/server/models/activitypub/actor-follow.ts
@@ -32,6 +32,7 @@ import {
32 MActorFollowActorsDefault, 32 MActorFollowActorsDefault,
33 MActorFollowActorsDefaultSubscription, 33 MActorFollowActorsDefaultSubscription,
34 MActorFollowFollowingHost, 34 MActorFollowFollowingHost,
35 MActorFollowFormattable,
35 MActorFollowSubscriptions 36 MActorFollowSubscriptions
36} from '@server/typings/models' 37} from '@server/typings/models'
37 38
@@ -580,7 +581,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
580 return ActorFollowModel.findAll(query) 581 return ActorFollowModel.findAll(query)
581 } 582 }
582 583
583 toFormattedJSON (): ActorFollow { 584 toFormattedJSON (this: MActorFollowFormattable): ActorFollow {
584 const follower = this.ActorFollower.toFormattedJSON() 585 const follower = this.ActorFollower.toFormattedJSON()
585 const following = this.ActorFollowing.toFormattedJSON() 586 const following = this.ActorFollowing.toFormattedJSON()
586 587
diff --git a/server/models/activitypub/actor.ts b/server/models/activitypub/actor.ts
index 2312127b4..e2213afa1 100644
--- a/server/models/activitypub/actor.ts
+++ b/server/models/activitypub/actor.ts
@@ -36,7 +36,16 @@ import { isOutdated, throwIfNotValid } from '../utils'
36import { VideoChannelModel } from '../video/video-channel' 36import { VideoChannelModel } from '../video/video-channel'
37import { ActorFollowModel } from './actor-follow' 37import { ActorFollowModel } from './actor-follow'
38import { VideoModel } from '../video/video' 38import { VideoModel } from '../video/video'
39import { MActor, MActorAccountChannelId, MActorFull } from '../../typings/models' 39import {
40 MActor,
41 MActorAccountChannelId,
42 MActorFormattable,
43 MActorFull, MActorHost,
44 MActorServer,
45 MActorSummaryFormattable,
46 MServerHost,
47 MActorRedundancyAllowed
48} from '../../typings/models'
40import * as Bluebird from 'bluebird' 49import * as Bluebird from 'bluebird'
41 50
42enum ScopeNames { 51enum ScopeNames {
@@ -393,24 +402,31 @@ export class ActorModel extends Model<ActorModel> {
393 }) 402 })
394 } 403 }
395 404
396 toFormattedJSON () { 405 toFormattedSummaryJSON (this: MActorSummaryFormattable) {
397 let avatar: Avatar = null 406 let avatar: Avatar = null
398 if (this.Avatar) { 407 if (this.Avatar) {
399 avatar = this.Avatar.toFormattedJSON() 408 avatar = this.Avatar.toFormattedJSON()
400 } 409 }
401 410
402 return { 411 return {
403 id: this.id,
404 url: this.url, 412 url: this.url,
405 name: this.preferredUsername, 413 name: this.preferredUsername,
406 host: this.getHost(), 414 host: this.getHost(),
415 avatar
416 }
417 }
418
419 toFormattedJSON (this: MActorFormattable) {
420 const base = this.toFormattedSummaryJSON()
421
422 return Object.assign(base, {
423 id: this.id,
407 hostRedundancyAllowed: this.getRedundancyAllowed(), 424 hostRedundancyAllowed: this.getRedundancyAllowed(),
408 followingCount: this.followingCount, 425 followingCount: this.followingCount,
409 followersCount: this.followersCount, 426 followersCount: this.followersCount,
410 avatar,
411 createdAt: this.createdAt, 427 createdAt: this.createdAt,
412 updatedAt: this.updatedAt 428 updatedAt: this.updatedAt
413 } 429 })
414 } 430 }
415 431
416 toActivityPubObject (name: string, type: 'Account' | 'Application' | 'VideoChannel') { 432 toActivityPubObject (name: string, type: 'Account' | 'Application' | 'VideoChannel') {
@@ -500,7 +516,7 @@ export class ActorModel extends Model<ActorModel> {
500 return this.serverId === null 516 return this.serverId === null
501 } 517 }
502 518
503 getWebfingerUrl () { 519 getWebfingerUrl (this: MActorServer) {
504 return 'acct:' + this.preferredUsername + '@' + this.getHost() 520 return 'acct:' + this.preferredUsername + '@' + this.getHost()
505 } 521 }
506 522
@@ -508,11 +524,11 @@ export class ActorModel extends Model<ActorModel> {
508 return this.Server ? `${this.preferredUsername}@${this.Server.host}` : this.preferredUsername 524 return this.Server ? `${this.preferredUsername}@${this.Server.host}` : this.preferredUsername
509 } 525 }
510 526
511 getHost () { 527 getHost (this: MActorHost) {
512 return this.Server ? this.Server.host : WEBSERVER.HOST 528 return this.Server ? this.Server.host : WEBSERVER.HOST
513 } 529 }
514 530
515 getRedundancyAllowed () { 531 getRedundancyAllowed (this: MActorRedundancyAllowed) {
516 return this.Server ? this.Server.redundancyAllowed : false 532 return this.Server ? this.Server.redundancyAllowed : false
517 } 533 }
518 534
diff --git a/server/models/avatar/avatar.ts b/server/models/avatar/avatar.ts
index b40144592..950e4b181 100644
--- a/server/models/avatar/avatar.ts
+++ b/server/models/avatar/avatar.ts
@@ -7,6 +7,7 @@ import { remove } from 'fs-extra'
7import { CONFIG } from '../../initializers/config' 7import { CONFIG } from '../../initializers/config'
8import { throwIfNotValid } from '../utils' 8import { throwIfNotValid } from '../utils'
9import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' 9import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
10import { MAvatarFormattable } from '@server/typings/models'
10 11
11@Table({ 12@Table({
12 tableName: 'avatar', 13 tableName: 'avatar',
@@ -57,7 +58,7 @@ export class AvatarModel extends Model<AvatarModel> {
57 return AvatarModel.findOne(query) 58 return AvatarModel.findOne(query)
58 } 59 }
59 60
60 toFormattedJSON (): Avatar { 61 toFormattedJSON (this: MAvatarFormattable): Avatar {
61 return { 62 return {
62 path: this.getStaticPath(), 63 path: this.getStaticPath(),
63 createdAt: this.createdAt, 64 createdAt: this.createdAt,
diff --git a/server/models/server/plugin.ts b/server/models/server/plugin.ts
index debd25ea1..d094da1f5 100644
--- a/server/models/server/plugin.ts
+++ b/server/models/server/plugin.ts
@@ -12,7 +12,7 @@ import { PeerTubePlugin } from '../../../shared/models/plugins/peertube-plugin.m
12import { FindAndCountOptions, json } from 'sequelize' 12import { FindAndCountOptions, json } from 'sequelize'
13import { RegisterServerSettingOptions } from '../../../shared/models/plugins/register-server-setting.model' 13import { RegisterServerSettingOptions } from '../../../shared/models/plugins/register-server-setting.model'
14import * as Bluebird from 'bluebird' 14import * as Bluebird from 'bluebird'
15import { MPlugin } from '@server/typings/models' 15import { MPlugin, MPluginFormattable } from '@server/typings/models'
16 16
17@DefaultScope(() => ({ 17@DefaultScope(() => ({
18 attributes: { 18 attributes: {
@@ -253,7 +253,7 @@ export class PluginModel extends Model<PluginModel> {
253 return result 253 return result
254 } 254 }
255 255
256 toFormattedJSON (): PeerTubePlugin { 256 toFormattedJSON (this: MPluginFormattable): PeerTubePlugin {
257 return { 257 return {
258 name: this.name, 258 name: this.name,
259 type: this.type, 259 type: this.type,
diff --git a/server/models/server/server-blocklist.ts b/server/models/server/server-blocklist.ts
index e4db93dfc..3e9687191 100644
--- a/server/models/server/server-blocklist.ts
+++ b/server/models/server/server-blocklist.ts
@@ -4,7 +4,7 @@ import { ServerModel } from './server'
4import { ServerBlock } from '../../../shared/models/blocklist' 4import { ServerBlock } from '../../../shared/models/blocklist'
5import { getSort } from '../utils' 5import { getSort } from '../utils'
6import * as Bluebird from 'bluebird' 6import * as Bluebird from 'bluebird'
7import { MServerBlocklist, MServerBlocklistAccountServer } from '@server/typings/models' 7import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/typings/models'
8 8
9enum ScopeNames { 9enum ScopeNames {
10 WITH_ACCOUNT = 'WITH_ACCOUNT', 10 WITH_ACCOUNT = 'WITH_ACCOUNT',
@@ -112,7 +112,7 @@ export class ServerBlocklistModel extends Model<ServerBlocklistModel> {
112 }) 112 })
113 } 113 }
114 114
115 toFormattedJSON (): ServerBlock { 115 toFormattedJSON (this: MServerBlocklistFormattable): ServerBlock {
116 return { 116 return {
117 byAccount: this.ByAccount.toFormattedJSON(), 117 byAccount: this.ByAccount.toFormattedJSON(),
118 blockedServer: this.BlockedServer.toFormattedJSON(), 118 blockedServer: this.BlockedServer.toFormattedJSON(),
diff --git a/server/models/server/server.ts b/server/models/server/server.ts
index b0bdd2b0b..3b6759b5c 100644
--- a/server/models/server/server.ts
+++ b/server/models/server/server.ts
@@ -4,7 +4,7 @@ import { ActorModel } from '../activitypub/actor'
4import { throwIfNotValid } from '../utils' 4import { throwIfNotValid } from '../utils'
5import { ServerBlocklistModel } from './server-blocklist' 5import { ServerBlocklistModel } from './server-blocklist'
6import * as Bluebird from 'bluebird' 6import * as Bluebird from 'bluebird'
7import { MServer } from '@server/typings/models/server' 7import { MServer, MServerFormattable } from '@server/typings/models/server'
8 8
9@Table({ 9@Table({
10 tableName: 'server', 10 tableName: 'server',
@@ -65,7 +65,7 @@ export class ServerModel extends Model<ServerModel> {
65 return this.BlockedByAccounts && this.BlockedByAccounts.length !== 0 65 return this.BlockedByAccounts && this.BlockedByAccounts.length !== 0
66 } 66 }
67 67
68 toFormattedJSON () { 68 toFormattedJSON (this: MServerFormattable) {
69 return { 69 return {
70 host: this.host 70 host: this.host
71 } 71 }
diff --git a/server/models/video/schedule-video-update.ts b/server/models/video/schedule-video-update.ts
index 603d55692..fc2a424aa 100644
--- a/server/models/video/schedule-video-update.ts
+++ b/server/models/video/schedule-video-update.ts
@@ -2,6 +2,7 @@ import { AllowNull, BelongsTo, Column, CreatedAt, Default, ForeignKey, Model, Ta
2import { ScopeNames as VideoScopeNames, VideoModel } from './video' 2import { ScopeNames as VideoScopeNames, VideoModel } from './video'
3import { VideoPrivacy } from '../../../shared/models/videos' 3import { VideoPrivacy } from '../../../shared/models/videos'
4import { Op, Transaction } from 'sequelize' 4import { Op, Transaction } from 'sequelize'
5import { MScheduleVideoUpdateFormattable } from '@server/typings/models'
5 6
6@Table({ 7@Table({
7 tableName: 'scheduleVideoUpdate', 8 tableName: 'scheduleVideoUpdate',
@@ -96,7 +97,7 @@ export class ScheduleVideoUpdateModel extends Model<ScheduleVideoUpdateModel> {
96 return ScheduleVideoUpdateModel.destroy(query) 97 return ScheduleVideoUpdateModel.destroy(query)
97 } 98 }
98 99
99 toFormattedJSON () { 100 toFormattedJSON (this: MScheduleVideoUpdateFormattable) {
100 return { 101 return {
101 updateAt: this.updateAt, 102 updateAt: this.updateAt,
102 privacy: this.privacy || undefined 103 privacy: this.privacy || undefined
diff --git a/server/models/video/video-abuse.ts b/server/models/video/video-abuse.ts
index af7b40d11..6ef1a915d 100644
--- a/server/models/video/video-abuse.ts
+++ b/server/models/video/video-abuse.ts
@@ -11,7 +11,7 @@ import { getSort, throwIfNotValid } from '../utils'
11import { VideoModel } from './video' 11import { VideoModel } from './video'
12import { VideoAbuseState } from '../../../shared' 12import { VideoAbuseState } from '../../../shared'
13import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants' 13import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants'
14import { MVideoAbuse, MVideoAbuseAccountVideo, MVideoAbuseVideo } from '../../typings/models' 14import { MVideoAbuse, MVideoAbuseFormattable, MVideoAbuseVideo } from '../../typings/models'
15import * as Bluebird from 'bluebird' 15import * as Bluebird from 'bluebird'
16 16
17@Table({ 17@Table({
@@ -108,7 +108,7 @@ export class VideoAbuseModel extends Model<VideoAbuseModel> {
108 }) 108 })
109 } 109 }
110 110
111 toFormattedJSON (this: MVideoAbuseAccountVideo): VideoAbuse { 111 toFormattedJSON (this: MVideoAbuseFormattable): VideoAbuse {
112 return { 112 return {
113 id: this.id, 113 id: this.id,
114 reason: this.reason, 114 reason: this.reason,
diff --git a/server/models/video/video-blacklist.ts b/server/models/video/video-blacklist.ts
index 5a0cac94a..b4df6cd6a 100644
--- a/server/models/video/video-blacklist.ts
+++ b/server/models/video/video-blacklist.ts
@@ -8,7 +8,7 @@ import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
8import { FindOptions } from 'sequelize' 8import { FindOptions } from 'sequelize'
9import { ThumbnailModel } from './thumbnail' 9import { ThumbnailModel } from './thumbnail'
10import * as Bluebird from 'bluebird' 10import * as Bluebird from 'bluebird'
11import { MVideoBlacklist } from '@server/typings/models' 11import { MVideoBlacklist, MVideoBlacklistFormattable } from '@server/typings/models'
12 12
13@Table({ 13@Table({
14 tableName: 'videoBlacklist', 14 tableName: 'videoBlacklist',
@@ -111,7 +111,7 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
111 return VideoBlacklistModel.findOne(query) 111 return VideoBlacklistModel.findOne(query)
112 } 112 }
113 113
114 toFormattedJSON (): VideoBlacklist { 114 toFormattedJSON (this: MVideoBlacklistFormattable): VideoBlacklist {
115 return { 115 return {
116 id: this.id, 116 id: this.id,
117 createdAt: this.createdAt, 117 createdAt: this.createdAt,
diff --git a/server/models/video/video-caption.ts b/server/models/video/video-caption.ts
index 9ce350d12..ad5801768 100644
--- a/server/models/video/video-caption.ts
+++ b/server/models/video/video-caption.ts
@@ -22,7 +22,7 @@ import { logger } from '../../helpers/logger'
22import { remove } from 'fs-extra' 22import { remove } from 'fs-extra'
23import { CONFIG } from '../../initializers/config' 23import { CONFIG } from '../../initializers/config'
24import * as Bluebird from 'bluebird' 24import * as Bluebird from 'bluebird'
25import { MVideoCaptionVideo } from '@server/typings/models' 25import { MVideoCaptionFormattable, MVideoCaptionVideo } from '@server/typings/models'
26 26
27export enum ScopeNames { 27export enum ScopeNames {
28 WITH_VIDEO_UUID_AND_REMOTE = 'WITH_VIDEO_UUID_AND_REMOTE' 28 WITH_VIDEO_UUID_AND_REMOTE = 'WITH_VIDEO_UUID_AND_REMOTE'
@@ -154,7 +154,7 @@ export class VideoCaptionModel extends Model<VideoCaptionModel> {
154 return this.Video.remote === false 154 return this.Video.remote === false
155 } 155 }
156 156
157 toFormattedJSON (): VideoCaption { 157 toFormattedJSON (this: MVideoCaptionFormattable): VideoCaption {
158 return { 158 return {
159 language: { 159 language: {
160 id: this.language, 160 id: this.language,
@@ -164,15 +164,15 @@ export class VideoCaptionModel extends Model<VideoCaptionModel> {
164 } 164 }
165 } 165 }
166 166
167 getCaptionStaticPath () { 167 getCaptionStaticPath (this: MVideoCaptionFormattable) {
168 return join(LAZY_STATIC_PATHS.VIDEO_CAPTIONS, this.getCaptionName()) 168 return join(LAZY_STATIC_PATHS.VIDEO_CAPTIONS, this.getCaptionName())
169 } 169 }
170 170
171 getCaptionName () { 171 getCaptionName (this: MVideoCaptionFormattable) {
172 return `${this.Video.uuid}-${this.language}.vtt` 172 return `${this.Video.uuid}-${this.language}.vtt`
173 } 173 }
174 174
175 removeCaptionFile () { 175 removeCaptionFile (this: MVideoCaptionFormattable) {
176 return remove(CONFIG.STORAGE.CAPTIONS_DIR + this.getCaptionName()) 176 return remove(CONFIG.STORAGE.CAPTIONS_DIR + this.getCaptionName())
177 } 177 }
178} 178}
diff --git a/server/models/video/video-change-ownership.ts b/server/models/video/video-change-ownership.ts
index 2d0ff48fb..f7a351329 100644
--- a/server/models/video/video-change-ownership.ts
+++ b/server/models/video/video-change-ownership.ts
@@ -3,7 +3,7 @@ import { AccountModel } from '../account/account'
3import { ScopeNames as VideoScopeNames, VideoModel } from './video' 3import { ScopeNames as VideoScopeNames, VideoModel } from './video'
4import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '../../../shared/models/videos' 4import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '../../../shared/models/videos'
5import { getSort } from '../utils' 5import { getSort } from '../utils'
6import { MVideoChangeOwnershipFull } from '@server/typings/models/video/video-change-ownership' 6import { MVideoChangeOwnershipFormattable, MVideoChangeOwnershipFull } from '@server/typings/models/video/video-change-ownership'
7import * as Bluebird from 'bluebird' 7import * as Bluebird from 'bluebird'
8 8
9enum ScopeNames { 9enum ScopeNames {
@@ -119,7 +119,7 @@ export class VideoChangeOwnershipModel extends Model<VideoChangeOwnershipModel>
119 .findByPk(id) 119 .findByPk(id)
120 } 120 }
121 121
122 toFormattedJSON (): VideoChangeOwnership { 122 toFormattedJSON (this: MVideoChangeOwnershipFormattable): VideoChangeOwnership {
123 return { 123 return {
124 id: this.id, 124 id: this.id,
125 status: this.status, 125 status: this.status,
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts
index b6a60827f..7a4df516a 100644
--- a/server/models/video/video-channel.ts
+++ b/server/models/video/video-channel.ts
@@ -37,7 +37,7 @@ import * as Bluebird from 'bluebird'
37import { 37import {
38 MChannelAccountDefault, 38 MChannelAccountDefault,
39 MChannelActor, 39 MChannelActor,
40 MChannelActorAccountDefaultVideos 40 MChannelActorAccountDefaultVideos, MChannelSummaryFormattable, MChannelFormattable
41} from '../../typings/models/video' 41} from '../../typings/models/video'
42 42
43// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation 43// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
@@ -482,7 +482,20 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
482 .findByPk(id, options) 482 .findByPk(id, options)
483 } 483 }
484 484
485 toFormattedJSON (): VideoChannel { 485 toFormattedSummaryJSON (this: MChannelSummaryFormattable): VideoChannelSummary {
486 const actor = this.Actor.toFormattedSummaryJSON()
487
488 return {
489 id: this.id,
490 name: actor.name,
491 displayName: this.getDisplayName(),
492 url: actor.url,
493 host: actor.host,
494 avatar: actor.avatar
495 }
496 }
497
498 toFormattedJSON (this: MChannelFormattable): VideoChannel {
486 const actor = this.Actor.toFormattedJSON() 499 const actor = this.Actor.toFormattedJSON()
487 const videoChannel = { 500 const videoChannel = {
488 id: this.id, 501 id: this.id,
@@ -500,19 +513,6 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
500 return Object.assign(actor, videoChannel) 513 return Object.assign(actor, videoChannel)
501 } 514 }
502 515
503 toFormattedSummaryJSON (): VideoChannelSummary {
504 const actor = this.Actor.toFormattedJSON()
505
506 return {
507 id: this.id,
508 name: actor.name,
509 displayName: this.getDisplayName(),
510 url: actor.url,
511 host: actor.host,
512 avatar: actor.avatar
513 }
514 }
515
516 toActivityPubObject (): ActivityPubActor { 516 toActivityPubObject (): ActivityPubActor {
517 const obj = this.Actor.toActivityPubObject(this.name, 'VideoChannel') 517 const obj = this.Actor.toActivityPubObject(this.name, 'VideoChannel')
518 518
diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts
index c88dac1c1..84d71c553 100644
--- a/server/models/video/video-comment.ts
+++ b/server/models/video/video-comment.ts
@@ -17,6 +17,7 @@ import { FindOptions, Op, Order, ScopeOptions, Sequelize, Transaction } from 'se
17import * as Bluebird from 'bluebird' 17import * as Bluebird from 'bluebird'
18import { 18import {
19 MComment, 19 MComment,
20 MCommentFormattable,
20 MCommentId, 21 MCommentId,
21 MCommentOwner, 22 MCommentOwner,
22 MCommentOwnerReplyVideoLight, 23 MCommentOwnerReplyVideoLight,
@@ -475,7 +476,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
475 return uniq(result) 476 return uniq(result)
476 } 477 }
477 478
478 toFormattedJSON () { 479 toFormattedJSON (this: MCommentFormattable) {
479 return { 480 return {
480 id: this.id, 481 id: this.id,
481 url: this.url, 482 url: this.url,
diff --git a/server/models/video/video-format-utils.ts b/server/models/video/video-format-utils.ts
index 4e7eb5f0c..6aa7c1e3e 100644
--- a/server/models/video/video-format-utils.ts
+++ b/server/models/video/video-format-utils.ts
@@ -16,7 +16,7 @@ import {
16} from '../../lib/activitypub' 16} from '../../lib/activitypub'
17import { isArray } from '../../helpers/custom-validators/misc' 17import { isArray } from '../../helpers/custom-validators/misc'
18import { VideoStreamingPlaylist } from '../../../shared/models/videos/video-streaming-playlist.model' 18import { VideoStreamingPlaylist } from '../../../shared/models/videos/video-streaming-playlist.model'
19import { MVideo, MVideoAP, MVideoDetails } from '../../typings/models' 19import { MVideo, MVideoAP, MVideoFormattable, MVideoFormattableDetails } from '../../typings/models'
20import { MStreamingPlaylistRedundancies } from '../../typings/models/video/video-streaming-playlist' 20import { MStreamingPlaylistRedundancies } from '../../typings/models/video/video-streaming-playlist'
21import { MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file' 21import { MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file'
22 22
@@ -29,7 +29,7 @@ export type VideoFormattingJSONOptions = {
29 blacklistInfo?: boolean 29 blacklistInfo?: boolean
30 } 30 }
31} 31}
32function videoModelToFormattedJSON (video: VideoModel, options?: VideoFormattingJSONOptions): Video { 32function videoModelToFormattedJSON (video: MVideoFormattable, options?: VideoFormattingJSONOptions): Video {
33 const userHistory = isArray(video.UserVideoHistories) ? video.UserVideoHistories[0] : undefined 33 const userHistory = isArray(video.UserVideoHistories) ? video.UserVideoHistories[0] : undefined
34 34
35 const videoObject: Video = { 35 const videoObject: Video = {
@@ -103,7 +103,7 @@ function videoModelToFormattedJSON (video: VideoModel, options?: VideoFormatting
103 return videoObject 103 return videoObject
104} 104}
105 105
106function videoModelToFormattedDetailsJSON (video: MVideoDetails): VideoDetails { 106function videoModelToFormattedDetailsJSON (video: MVideoFormattableDetails): VideoDetails {
107 const formattedJson = video.toFormattedJSON({ 107 const formattedJson = video.toFormattedJSON({
108 additionalAttributes: { 108 additionalAttributes: {
109 scheduledUpdate: true, 109 scheduledUpdate: true,
diff --git a/server/models/video/video-import.ts b/server/models/video/video-import.ts
index f596eea9d..af5314ce9 100644
--- a/server/models/video/video-import.ts
+++ b/server/models/video/video-import.ts
@@ -21,7 +21,7 @@ import { VideoImport, VideoImportState } from '../../../shared'
21import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos' 21import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos'
22import { UserModel } from '../account/user' 22import { UserModel } from '../account/user'
23import * as Bluebird from 'bluebird' 23import * as Bluebird from 'bluebird'
24import { MVideoImportDefault } from '@server/typings/models/video/video-import' 24import { MVideoImportDefault, MVideoImportFormattable } from '@server/typings/models/video/video-import'
25 25
26@DefaultScope(() => ({ 26@DefaultScope(() => ({
27 include: [ 27 include: [
@@ -154,7 +154,7 @@ export class VideoImportModel extends Model<VideoImportModel> {
154 return this.targetUrl || this.magnetUri || this.torrentName 154 return this.targetUrl || this.magnetUri || this.torrentName
155 } 155 }
156 156
157 toFormattedJSON (): VideoImport { 157 toFormattedJSON (this: MVideoImportFormattable): VideoImport {
158 const videoFormatOptions = { 158 const videoFormatOptions = {
159 completeDescription: true, 159 completeDescription: true,
160 additionalAttributes: { state: true, waitTranscoding: true, scheduledUpdate: true } 160 additionalAttributes: { state: true, waitTranscoding: true, scheduledUpdate: true }
diff --git a/server/models/video/video-playlist-element.ts b/server/models/video/video-playlist-element.ts
index 901113161..80ca22a18 100644
--- a/server/models/video/video-playlist-element.ts
+++ b/server/models/video/video-playlist-element.ts
@@ -21,12 +21,16 @@ import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
21import { PlaylistElementObject } from '../../../shared/models/activitypub/objects/playlist-element-object' 21import { PlaylistElementObject } from '../../../shared/models/activitypub/objects/playlist-element-object'
22import * as validator from 'validator' 22import * as validator from 'validator'
23import { AggregateOptions, Op, ScopeOptions, Sequelize, Transaction } from 'sequelize' 23import { AggregateOptions, Op, ScopeOptions, Sequelize, Transaction } from 'sequelize'
24import { UserModel } from '../account/user'
25import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../shared/models/videos/playlist/video-playlist-element.model' 24import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../shared/models/videos/playlist/video-playlist-element.model'
26import { AccountModel } from '../account/account' 25import { AccountModel } from '../account/account'
27import { VideoPrivacy } from '../../../shared/models/videos' 26import { VideoPrivacy } from '../../../shared/models/videos'
28import * as Bluebird from 'bluebird' 27import * as Bluebird from 'bluebird'
29import { MVideoPlaylistAP, MVideoPlaylistElement, MVideoPlaylistVideoThumbnail } from '@server/typings/models/video/video-playlist-element' 28import {
29 MVideoPlaylistElement,
30 MVideoPlaylistElementAP,
31 MVideoPlaylistElementFormattable,
32 MVideoPlaylistVideoThumbnail
33} from '@server/typings/models/video/video-playlist-element'
30import { MUserAccountId } from '@server/typings/models' 34import { MUserAccountId } from '@server/typings/models'
31 35
32@Table({ 36@Table({
@@ -180,7 +184,7 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
180 return VideoPlaylistElementModel.findByPk(playlistElementId) 184 return VideoPlaylistElementModel.findByPk(playlistElementId)
181 } 185 }
182 186
183 static loadByPlaylistAndVideoForAP (playlistId: number | string, videoId: number | string): Bluebird<MVideoPlaylistAP> { 187 static loadByPlaylistAndVideoForAP (playlistId: number | string, videoId: number | string): Bluebird<MVideoPlaylistElementAP> {
184 const playlistWhere = validator.isUUID('' + playlistId) ? { uuid: playlistId } : { id: playlistId } 188 const playlistWhere = validator.isUUID('' + playlistId) ? { uuid: playlistId } : { id: playlistId }
185 const videoWhere = validator.isUUID('' + videoId) ? { uuid: videoId } : { id: videoId } 189 const videoWhere = validator.isUUID('' + videoId) ? { uuid: videoId } : { id: videoId }
186 190
@@ -293,7 +297,7 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
293 return VideoPlaylistElementModel.increment({ position: by }, query) 297 return VideoPlaylistElementModel.increment({ position: by }, query)
294 } 298 }
295 299
296 getType (displayNSFW?: boolean, accountId?: number) { 300 getType (this: MVideoPlaylistElementFormattable, displayNSFW?: boolean, accountId?: number) {
297 const video = this.Video 301 const video = this.Video
298 302
299 if (!video) return VideoPlaylistElementType.DELETED 303 if (!video) return VideoPlaylistElementType.DELETED
@@ -309,14 +313,17 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
309 return VideoPlaylistElementType.REGULAR 313 return VideoPlaylistElementType.REGULAR
310 } 314 }
311 315
312 getVideoElement (displayNSFW?: boolean, accountId?: number) { 316 getVideoElement (this: MVideoPlaylistElementFormattable, displayNSFW?: boolean, accountId?: number) {
313 if (!this.Video) return null 317 if (!this.Video) return null
314 if (this.getType(displayNSFW, accountId) !== VideoPlaylistElementType.REGULAR) return null 318 if (this.getType(displayNSFW, accountId) !== VideoPlaylistElementType.REGULAR) return null
315 319
316 return this.Video.toFormattedJSON() 320 return this.Video.toFormattedJSON()
317 } 321 }
318 322
319 toFormattedJSON (options: { displayNSFW?: boolean, accountId?: number } = {}): VideoPlaylistElement { 323 toFormattedJSON (
324 this: MVideoPlaylistElementFormattable,
325 options: { displayNSFW?: boolean, accountId?: number } = {}
326 ): VideoPlaylistElement {
320 return { 327 return {
321 id: this.id, 328 id: this.id,
322 position: this.position, 329 position: this.position,
diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts
index 9f1d03ac5..80dd65322 100644
--- a/server/models/video/video-playlist.ts
+++ b/server/models/video/video-playlist.ts
@@ -46,6 +46,7 @@ import { FindOptions, literal, Op, ScopeOptions, Transaction, WhereOptions } fro
46import * as Bluebird from 'bluebird' 46import * as Bluebird from 'bluebird'
47import { 47import {
48 MVideoPlaylistAccountThumbnail, 48 MVideoPlaylistAccountThumbnail,
49 MVideoPlaylistFormattable,
49 MVideoPlaylistFull, 50 MVideoPlaylistFull,
50 MVideoPlaylistFullSummary, 51 MVideoPlaylistFullSummary,
51 MVideoPlaylistIdWithElements 52 MVideoPlaylistIdWithElements
@@ -479,7 +480,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
479 return isOutdated(this, ACTIVITY_PUB.VIDEO_PLAYLIST_REFRESH_INTERVAL) 480 return isOutdated(this, ACTIVITY_PUB.VIDEO_PLAYLIST_REFRESH_INTERVAL)
480 } 481 }
481 482
482 toFormattedJSON (): VideoPlaylist { 483 toFormattedJSON (this: MVideoPlaylistFormattable): VideoPlaylist {
483 return { 484 return {
484 id: this.id, 485 id: this.id,
485 uuid: this.uuid, 486 uuid: this.uuid,
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index e62bde344..9c24d1ba8 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -132,8 +132,9 @@ import {
132 MVideoFullLight, 132 MVideoFullLight,
133 MVideoIdThumbnail, 133 MVideoIdThumbnail,
134 MVideoThumbnail, 134 MVideoThumbnail,
135 MVideoWithAllFiles, 135 MVideoWithAllFiles, MVideoWithFile,
136 MVideoWithRights 136 MVideoWithRights,
137 MVideoFormattable
137} from '../../typings/models' 138} from '../../typings/models'
138import { MVideoFile, MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file' 139import { MVideoFile, MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file'
139import { MThumbnail } from '../../typings/models/video/thumbnail' 140import { MThumbnail } from '../../typings/models/video/thumbnail'
@@ -1765,14 +1766,14 @@ export class VideoModel extends Model<VideoModel> {
1765 this.VideoChannel.Account.isBlocked() 1766 this.VideoChannel.Account.isBlocked()
1766 } 1767 }
1767 1768
1768 getOriginalFile () { 1769 getOriginalFile <T extends MVideoWithFile> (this: T) {
1769 if (Array.isArray(this.VideoFiles) === false) return undefined 1770 if (Array.isArray(this.VideoFiles) === false) return undefined
1770 1771
1771 // The original file is the file that have the higher resolution 1772 // The original file is the file that have the higher resolution
1772 return maxBy(this.VideoFiles, file => file.resolution) 1773 return maxBy(this.VideoFiles, file => file.resolution)
1773 } 1774 }
1774 1775
1775 getFile (resolution: number) { 1776 getFile <T extends MVideoWithFile> (this: T, resolution: number) {
1776 if (Array.isArray(this.VideoFiles) === false) return undefined 1777 if (Array.isArray(this.VideoFiles) === false) return undefined
1777 1778
1778 return this.VideoFiles.find(f => f.resolution === resolution) 1779 return this.VideoFiles.find(f => f.resolution === resolution)
@@ -1878,7 +1879,7 @@ export class VideoModel extends Model<VideoModel> {
1878 return join(LAZY_STATIC_PATHS.PREVIEWS, preview.filename) 1879 return join(LAZY_STATIC_PATHS.PREVIEWS, preview.filename)
1879 } 1880 }
1880 1881
1881 toFormattedJSON (options?: VideoFormattingJSONOptions): Video { 1882 toFormattedJSON <T extends MVideoFormattable> (this: T, options?: VideoFormattingJSONOptions): Video {
1882 return videoModelToFormattedJSON(this, options) 1883 return videoModelToFormattedJSON(this, options)
1883 } 1884 }
1884 1885
diff --git a/server/typings/models/account/account-blocklist.ts b/server/typings/models/account/account-blocklist.ts
index d20d97aa8..c9cb55332 100644
--- a/server/typings/models/account/account-blocklist.ts
+++ b/server/typings/models/account/account-blocklist.ts
@@ -1,6 +1,6 @@
1import { AccountBlocklistModel } from '../../../models/account/account-blocklist' 1import { AccountBlocklistModel } from '../../../models/account/account-blocklist'
2import { PickWith } from '../../utils' 2import { PickWith } from '../../utils'
3import { MAccountDefault } from './account' 3import { MAccountDefault, MAccountFormattable } from './account'
4 4
5type Use<K extends keyof AccountBlocklistModel, M> = PickWith<AccountBlocklistModel, K, M> 5type Use<K extends keyof AccountBlocklistModel, M> = PickWith<AccountBlocklistModel, K, M>
6 6
@@ -15,3 +15,11 @@ export type MAccountBlocklistId = Pick<AccountBlocklistModel, 'id'>
15export type MAccountBlocklistAccounts = MAccountBlocklist & 15export type MAccountBlocklistAccounts = MAccountBlocklist &
16 Use<'ByAccount', MAccountDefault> & 16 Use<'ByAccount', MAccountDefault> &
17 Use<'BlockedAccount', MAccountDefault> 17 Use<'BlockedAccount', MAccountDefault>
18
19// ############################################################################
20
21// Format for API or AP object
22
23export type MAccountBlocklistFormattable = Pick<MAccountBlocklist, 'createdAt'> &
24 Use<'ByAccount', MAccountFormattable> &
25 Use<'BlockedAccount', MAccountFormattable>
diff --git a/server/typings/models/account/account.ts b/server/typings/models/account/account.ts
index 9a8784e6b..33940517e 100644
--- a/server/typings/models/account/account.ts
+++ b/server/typings/models/account/account.ts
@@ -9,9 +9,11 @@ import {
9 MActorId, 9 MActorId,
10 MActorServer, 10 MActorServer,
11 MActorSummary, 11 MActorSummary,
12 MActorUrl 12 MActorSummaryFormattable,
13 MActorUrl,
14 MActorFormattable
13} from './actor' 15} from './actor'
14import { PickWith } from '../../utils' 16import { FunctionProperties, PickWith } from '../../utils'
15import { MAccountBlocklistId } from './account-blocklist' 17import { MAccountBlocklistId } from './account-blocklist'
16import { MChannelDefault } from '@server/typings/models' 18import { MChannelDefault } from '@server/typings/models'
17 19
@@ -67,7 +69,8 @@ export type MAccountServer = MAccount &
67 69
68// For API 70// For API
69 71
70export type MAccountSummary = Pick<MAccount, 'id' | 'name'> & 72export type MAccountSummary = FunctionProperties<MAccount> &
73 Pick<MAccount, 'id' | 'name'> &
71 Use<'Actor', MActorSummary> 74 Use<'Actor', MActorSummary>
72 75
73export type MAccountSummaryBlocks = MAccountSummary & 76export type MAccountSummaryBlocks = MAccountSummary &
@@ -75,3 +78,15 @@ export type MAccountSummaryBlocks = MAccountSummary &
75 78
76export type MAccountAPI = MAccount & 79export type MAccountAPI = MAccount &
77 Use<'Actor', MActorAPI> 80 Use<'Actor', MActorAPI>
81
82// ############################################################################
83
84// Format for API or AP object
85
86export type MAccountSummaryFormattable = FunctionProperties<MAccount> &
87 Pick<MAccount, 'id' | 'name'> &
88 Use<'Actor', MActorSummaryFormattable>
89
90export type MAccountFormattable = FunctionProperties<MAccount> &
91 Pick<MAccount, 'id' | 'name' | 'description' | 'createdAt' | 'updatedAt' | 'userId'> &
92 Use<'Actor', MActorFormattable>
diff --git a/server/typings/models/account/actor-follow.ts b/server/typings/models/account/actor-follow.ts
index 87050ac63..17a47b8df 100644
--- a/server/typings/models/account/actor-follow.ts
+++ b/server/typings/models/account/actor-follow.ts
@@ -3,14 +3,15 @@ import {
3 MActor, 3 MActor,
4 MActorAccount, 4 MActorAccount,
5 MActorAccountChannel, 5 MActorAccountChannel,
6 MActorChannel,
7 MActorChannelAccountActor, 6 MActorChannelAccountActor,
8 MActorDefault, 7 MActorDefault,
8 MActorFormattable,
9 MActorHost, 9 MActorHost,
10 MActorUsername 10 MActorUsername
11} from './actor' 11} from './actor'
12import { PickWith } from '../../utils' 12import { PickWith } from '../../utils'
13import { ActorModel } from '@server/models/activitypub/actor' 13import { ActorModel } from '@server/models/activitypub/actor'
14import { MChannelDefault } from '@server/typings/models'
14 15
15type Use<K extends keyof ActorFollowModel, M> = PickWith<ActorFollowModel, K, M> 16type Use<K extends keyof ActorFollowModel, M> = PickWith<ActorFollowModel, K, M>
16 17
@@ -43,9 +44,12 @@ export type MActorFollowFull = MActorFollow &
43 44
44// For subscriptions 45// For subscriptions
45 46
47type SubscriptionFollowing = MActorDefault &
48 PickWith<ActorModel, 'VideoChannel', MChannelDefault>
49
46export type MActorFollowActorsDefaultSubscription = MActorFollow & 50export type MActorFollowActorsDefaultSubscription = MActorFollow &
47 Use<'ActorFollower', MActorDefault> & 51 Use<'ActorFollower', MActorDefault> &
48 Use<'ActorFollowing', MActorDefault & MActorChannel> 52 Use<'ActorFollowing', SubscriptionFollowing>
49 53
50export type MActorFollowFollowingFullFollowerAccount = MActorFollow & 54export type MActorFollowFollowingFullFollowerAccount = MActorFollow &
51 Use<'ActorFollower', MActorAccount> & 55 Use<'ActorFollower', MActorAccount> &
@@ -53,3 +57,11 @@ export type MActorFollowFollowingFullFollowerAccount = MActorFollow &
53 57
54export type MActorFollowSubscriptions = MActorFollow & 58export type MActorFollowSubscriptions = MActorFollow &
55 Use<'ActorFollowing', MActorChannelAccountActor> 59 Use<'ActorFollowing', MActorChannelAccountActor>
60
61// ############################################################################
62
63// Format for API or AP object
64
65export type MActorFollowFormattable = Pick<MActorFollow, 'id' | 'score' | 'state' | 'createdAt' | 'updatedAt'> &
66 Use<'ActorFollower', MActorFormattable> &
67 Use<'ActorFollowing', MActorFormattable>
diff --git a/server/typings/models/account/actor.ts b/server/typings/models/account/actor.ts
index 7d99a433b..14ab2cd5b 100644
--- a/server/typings/models/account/actor.ts
+++ b/server/typings/models/account/actor.ts
@@ -1,8 +1,8 @@
1import { ActorModel } from '../../../models/activitypub/actor' 1import { ActorModel } from '../../../models/activitypub/actor'
2import { PickWith } from '../../utils' 2import { FunctionProperties, PickWith } from '../../utils'
3import { MAccount, MAccountDefault, MAccountId, MAccountIdActor } from './account' 3import { MAccount, MAccountDefault, MAccountId, MAccountIdActor } from './account'
4import { MServer, MServerHost, MServerHostBlocks } from '../server' 4import { MServer, MServerHost, MServerHostBlocks, MServerRedundancyAllowed } from '../server'
5import { MAvatar } from './avatar' 5import { MAvatar, MAvatarFormattable } from './avatar'
6import { MChannel, MChannelAccountActor, MChannelAccountDefault, MChannelId, MChannelIdActor } from '../video' 6import { MChannel, MChannelAccountActor, MChannelAccountDefault, MChannelId, MChannelIdActor } from '../video'
7 7
8type Use<K extends keyof ActorModel, M> = PickWith<ActorModel, K, M> 8type Use<K extends keyof ActorModel, M> = PickWith<ActorModel, K, M>
@@ -29,6 +29,7 @@ export type MActorLight = Omit<MActor, 'privateKey' | 'privateKey'>
29// Some association attributes 29// Some association attributes
30 30
31export type MActorHost = Use<'Server', MServerHost> 31export type MActorHost = Use<'Server', MServerHost>
32export type MActorRedundancyAllowed = Use<'Server', MServerRedundancyAllowed>
32 33
33export type MActorDefaultLight = MActorLight & 34export type MActorDefaultLight = MActorLight &
34 Use<'Server', MServerHost> & 35 Use<'Server', MServerHost> &
@@ -92,7 +93,8 @@ export type MActorFullActor = MActor &
92 93
93// API 94// API
94 95
95export type MActorSummary = Pick<MActor, 'id' | 'preferredUsername' | 'url' | 'serverId' | 'avatarId'> & 96export type MActorSummary = FunctionProperties<MActor> &
97 Pick<MActor, 'id' | 'preferredUsername' | 'url' | 'serverId' | 'avatarId'> &
96 Use<'Server', MServerHost> & 98 Use<'Server', MServerHost> &
97 Use<'Avatar', MAvatar> 99 Use<'Avatar', MAvatar>
98 100
@@ -101,3 +103,16 @@ export type MActorSummaryBlocks = MActorSummary &
101 103
102export type MActorAPI = Omit<MActorDefault, 'publicKey' | 'privateKey' | 'inboxUrl' | 'outboxUrl' | 'sharedInboxUrl' | 104export type MActorAPI = Omit<MActorDefault, 'publicKey' | 'privateKey' | 'inboxUrl' | 'outboxUrl' | 'sharedInboxUrl' |
103 'followersUrl' | 'followingUrl' | 'url' | 'createdAt' | 'updatedAt'> 105 'followersUrl' | 'followingUrl' | 'url' | 'createdAt' | 'updatedAt'>
106
107// ############################################################################
108
109// Format for API or AP object
110
111export type MActorSummaryFormattable = FunctionProperties<MActor> &
112 Pick<MActor, 'url' | 'preferredUsername'> &
113 Use<'Server', MServerHost> &
114 Use<'Avatar', MAvatarFormattable>
115
116export type MActorFormattable = MActorSummaryFormattable &
117 Pick<MActor, 'id' | 'followingCount' | 'followersCount' | 'createdAt' | 'updatedAt'> &
118 Use<'Server', MServer>
diff --git a/server/typings/models/account/avatar.ts b/server/typings/models/account/avatar.ts
index 257c48bfc..8af6cc787 100644
--- a/server/typings/models/account/avatar.ts
+++ b/server/typings/models/account/avatar.ts
@@ -1,3 +1,11 @@
1import { AvatarModel } from '../../../models/avatar/avatar' 1import { AvatarModel } from '../../../models/avatar/avatar'
2import { FunctionProperties } from '@server/typings/utils'
2 3
3export type MAvatar = AvatarModel 4export type MAvatar = AvatarModel
5
6// ############################################################################
7
8// Format for API or AP object
9
10export type MAvatarFormattable = FunctionProperties<MAvatar> &
11 Pick<MAvatar, 'filename' | 'createdAt' | 'updatedAt'>
diff --git a/server/typings/models/server/plugin.ts b/server/typings/models/server/plugin.ts
index b1e2e149d..94674c318 100644
--- a/server/typings/models/server/plugin.ts
+++ b/server/typings/models/server/plugin.ts
@@ -1,3 +1,10 @@
1import { PluginModel } from '@server/models/server/plugin' 1import { PluginModel } from '@server/models/server/plugin'
2 2
3export type MPlugin = PluginModel 3export type MPlugin = PluginModel
4
5// ############################################################################
6
7// Format for API or AP object
8
9export type MPluginFormattable = Pick<MPlugin, 'name' | 'type' | 'version' | 'latestVersion' | 'enabled' | 'uninstalled'
10 | 'peertubeEngine' | 'description' | 'homepage' | 'settings' | 'createdAt' | 'updatedAt'>
diff --git a/server/typings/models/server/server-blocklist.ts b/server/typings/models/server/server-blocklist.ts
index 0ca00b5c2..c81f604f5 100644
--- a/server/typings/models/server/server-blocklist.ts
+++ b/server/typings/models/server/server-blocklist.ts
@@ -1,6 +1,6 @@
1import { ServerBlocklistModel } from '@server/models/server/server-blocklist' 1import { ServerBlocklistModel } from '@server/models/server/server-blocklist'
2import { PickWith } from '@server/typings/utils' 2import { PickWith } from '@server/typings/utils'
3import { MAccountDefault, MServer } from '@server/typings/models' 3import { MAccountDefault, MAccountFormattable, MServer, MServerFormattable } from '@server/typings/models'
4 4
5type Use<K extends keyof ServerBlocklistModel, M> = PickWith<ServerBlocklistModel, K, M> 5type Use<K extends keyof ServerBlocklistModel, M> = PickWith<ServerBlocklistModel, K, M>
6 6
@@ -13,3 +13,11 @@ export type MServerBlocklist = Omit<ServerBlocklistModel, 'ByAccount' | 'Blocked
13export type MServerBlocklistAccountServer = MServerBlocklist & 13export type MServerBlocklistAccountServer = MServerBlocklist &
14 Use<'ByAccount', MAccountDefault> & 14 Use<'ByAccount', MAccountDefault> &
15 Use<'BlockedServer', MServer> 15 Use<'BlockedServer', MServer>
16
17// ############################################################################
18
19// Format for API or AP object
20
21export type MServerBlocklistFormattable = Pick<MServerBlocklist, 'createdAt'> &
22 Use<'ByAccount', MAccountFormattable> &
23 Use<'BlockedServer', MServerFormattable>
diff --git a/server/typings/models/server/server.ts b/server/typings/models/server/server.ts
index c059cff79..190cc0c28 100644
--- a/server/typings/models/server/server.ts
+++ b/server/typings/models/server/server.ts
@@ -1,5 +1,5 @@
1import { ServerModel } from '../../../models/server/server' 1import { ServerModel } from '../../../models/server/server'
2import { PickWith } from '../../utils' 2import { FunctionProperties, PickWith } from '../../utils'
3import { MAccountBlocklistId } from '../account' 3import { MAccountBlocklistId } from '../account'
4 4
5type Use<K extends keyof ServerModel, M> = PickWith<ServerModel, K, M> 5type Use<K extends keyof ServerModel, M> = PickWith<ServerModel, K, M>
@@ -11,6 +11,14 @@ export type MServer = Omit<ServerModel, 'Actors' | 'BlockedByAccounts'>
11// ############################################################################ 11// ############################################################################
12 12
13export type MServerHost = Pick<MServer, 'host'> 13export type MServerHost = Pick<MServer, 'host'>
14export type MServerRedundancyAllowed = Pick<MServer, 'redundancyAllowed'>
14 15
15export type MServerHostBlocks = MServerHost & 16export type MServerHostBlocks = MServerHost &
16 Use<'BlockedByAccounts', MAccountBlocklistId[]> 17 Use<'BlockedByAccounts', MAccountBlocklistId[]>
18
19// ############################################################################
20
21// Format for API or AP object
22
23export type MServerFormattable = FunctionProperties<MServer> &
24 Pick<MServer, 'host'>
diff --git a/server/typings/models/user/user-notification-setting.ts b/server/typings/models/user/user-notification-setting.ts
index 585d30a66..c674add1b 100644
--- a/server/typings/models/user/user-notification-setting.ts
+++ b/server/typings/models/user/user-notification-setting.ts
@@ -1,3 +1,9 @@
1import { UserNotificationSettingModel } from '@server/models/account/user-notification-setting' 1import { UserNotificationSettingModel } from '@server/models/account/user-notification-setting'
2 2
3export type MNotificationSetting = Omit<UserNotificationSettingModel, 'User'> 3export type MNotificationSetting = Omit<UserNotificationSettingModel, 'User'>
4
5// ############################################################################
6
7// Format for API or AP object
8
9export type MNotificationSettingFormattable = MNotificationSetting
diff --git a/server/typings/models/user/user.ts b/server/typings/models/user/user.ts
index 466cde33b..52d6d4a05 100644
--- a/server/typings/models/user/user.ts
+++ b/server/typings/models/user/user.ts
@@ -1,7 +1,17 @@
1import { UserModel } from '../../../models/account/user' 1import { UserModel } from '../../../models/account/user'
2import { PickWith } from '../../utils' 2import { PickWith, PickWithOpt } from '../../utils'
3import { MAccount, MAccountDefault, MAccountDefaultChannelDefault, MAccountId, MAccountIdActorId, MAccountUrl } from '../account' 3import {
4import { MNotificationSetting } from './user-notification-setting' 4 MAccount,
5 MAccountDefault,
6 MAccountDefaultChannelDefault,
7 MAccountFormattable,
8 MAccountId,
9 MAccountIdActorId,
10 MAccountUrl
11} from '../account'
12import { MNotificationSetting, MNotificationSettingFormattable } from './user-notification-setting'
13import { AccountModel } from '@server/models/account/account'
14import { MChannelFormattable } from '@server/typings/models'
5 15
6type Use<K extends keyof UserModel, M> = PickWith<UserModel, K, M> 16type Use<K extends keyof UserModel, M> = PickWith<UserModel, K, M>
7 17
@@ -11,6 +21,7 @@ export type MUser = Omit<UserModel, 'Account' | 'NotificationSetting' | 'VideoIm
11 21
12// ############################################################################ 22// ############################################################################
13 23
24export type MUserQuotaUsed = MUser & { videoQuotaUsed?: number, videoQuotaUsedDaily?: number }
14export type MUserId = Pick<UserModel, 'id'> 25export type MUserId = Pick<UserModel, 'id'>
15 26
16// ############################################################################ 27// ############################################################################
@@ -49,3 +60,11 @@ export type MUserNotifSettingAccount = MUser &
49export type MUserDefault = MUser & 60export type MUserDefault = MUser &
50 Use<'NotificationSetting', MNotificationSetting> & 61 Use<'NotificationSetting', MNotificationSetting> &
51 Use<'Account', MAccountDefault> 62 Use<'Account', MAccountDefault>
63
64// ############################################################################
65
66// Format for API or AP object
67
68export type MUserFormattable = MUserQuotaUsed &
69 Use<'Account', MAccountFormattable & PickWithOpt<AccountModel, 'VideoChannels', MChannelFormattable[]>> &
70 PickWithOpt<UserModel, 'NotificationSetting', MNotificationSettingFormattable>
diff --git a/server/typings/models/video/schedule-video-update.ts b/server/typings/models/video/schedule-video-update.ts
index 069705536..ada9af06e 100644
--- a/server/typings/models/video/schedule-video-update.ts
+++ b/server/typings/models/video/schedule-video-update.ts
@@ -1,3 +1,9 @@
1import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-update' 1import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-update'
2 2
3export type MScheduleVideoUpdate = Omit<ScheduleVideoUpdateModel, 'Video'> 3export type MScheduleVideoUpdate = Omit<ScheduleVideoUpdateModel, 'Video'>
4
5// ############################################################################
6
7// Format for API or AP object
8
9export type MScheduleVideoUpdateFormattable = Pick<MScheduleVideoUpdate, 'updateAt' | 'privacy'>
diff --git a/server/typings/models/video/video-abuse.ts b/server/typings/models/video/video-abuse.ts
index 0474cac5b..e38c3f586 100644
--- a/server/typings/models/video/video-abuse.ts
+++ b/server/typings/models/video/video-abuse.ts
@@ -1,7 +1,7 @@
1import { VideoAbuseModel } from '../../../models/video/video-abuse' 1import { VideoAbuseModel } from '../../../models/video/video-abuse'
2import { PickWith } from '../../utils' 2import { PickWith } from '../../utils'
3import { MVideo } from './video' 3import { MVideo } from './video'
4import { MAccountDefault } from '../account' 4import { MAccountDefault, MAccountFormattable } from '../account'
5 5
6type Use<K extends keyof VideoAbuseModel, M> = PickWith<VideoAbuseModel, K, M> 6type Use<K extends keyof VideoAbuseModel, M> = PickWith<VideoAbuseModel, K, M>
7 7
@@ -21,3 +21,11 @@ export type MVideoAbuseAccountVideo = MVideoAbuse &
21 Pick<VideoAbuseModel, 'toActivityPubObject'> & 21 Pick<VideoAbuseModel, 'toActivityPubObject'> &
22 Use<'Video', MVideo> & 22 Use<'Video', MVideo> &
23 Use<'Account', MAccountDefault> 23 Use<'Account', MAccountDefault>
24
25// ############################################################################
26
27// Format for API or AP object
28
29export type MVideoAbuseFormattable = MVideoAbuse &
30 Use<'Account', MAccountFormattable> &
31 Use<'Video', Pick<MVideo, 'id' | 'uuid' | 'name'>>
diff --git a/server/typings/models/video/video-blacklist.ts b/server/typings/models/video/video-blacklist.ts
index cc539f95c..1dedfa37f 100644
--- a/server/typings/models/video/video-blacklist.ts
+++ b/server/typings/models/video/video-blacklist.ts
@@ -1,6 +1,6 @@
1import { VideoBlacklistModel } from '../../../models/video/video-blacklist' 1import { VideoBlacklistModel } from '../../../models/video/video-blacklist'
2import { PickWith } from '@server/typings/utils' 2import { PickWith } from '@server/typings/utils'
3import { MVideo } from '@server/typings/models' 3import { MVideo, MVideoFormattable } from '@server/typings/models'
4 4
5type Use<K extends keyof VideoBlacklistModel, M> = PickWith<VideoBlacklistModel, K, M> 5type Use<K extends keyof VideoBlacklistModel, M> = PickWith<VideoBlacklistModel, K, M>
6 6
@@ -15,3 +15,10 @@ export type MVideoBlacklistUnfederated = Pick<MVideoBlacklist, 'unfederated'>
15 15
16export type MVideoBlacklistVideo = MVideoBlacklist & 16export type MVideoBlacklistVideo = MVideoBlacklist &
17 Use<'Video', MVideo> 17 Use<'Video', MVideo>
18
19// ############################################################################
20
21// Format for API or AP object
22
23export type MVideoBlacklistFormattable = MVideoBlacklist &
24 Use<'Video', MVideoFormattable>
diff --git a/server/typings/models/video/video-caption.ts b/server/typings/models/video/video-caption.ts
index fe0e664c2..7cb2a2ad3 100644
--- a/server/typings/models/video/video-caption.ts
+++ b/server/typings/models/video/video-caption.ts
@@ -1,6 +1,6 @@
1import { VideoCaptionModel } from '../../../models/video/video-caption' 1import { VideoCaptionModel } from '../../../models/video/video-caption'
2import { PickWith } from '@server/typings/utils' 2import { FunctionProperties, PickWith } from '@server/typings/utils'
3import { VideoModel } from '@server/models/video/video' 3import { MVideo, MVideoUUID } from '@server/typings/models'
4 4
5type Use<K extends keyof VideoCaptionModel, M> = PickWith<VideoCaptionModel, K, M> 5type Use<K extends keyof VideoCaptionModel, M> = PickWith<VideoCaptionModel, K, M>
6 6
@@ -13,4 +13,12 @@ export type MVideoCaption = Omit<VideoCaptionModel, 'Video'>
13export type MVideoCaptionLanguage = Pick<MVideoCaption, 'language'> 13export type MVideoCaptionLanguage = Pick<MVideoCaption, 'language'>
14 14
15export type MVideoCaptionVideo = MVideoCaption & 15export type MVideoCaptionVideo = MVideoCaption &
16 Use<'Video', Pick<VideoModel, 'id' | 'remote' | 'uuid'>> 16 Use<'Video', Pick<MVideo, 'id' | 'remote' | 'uuid'>>
17
18// ############################################################################
19
20// Format for API or AP object
21
22export type MVideoCaptionFormattable = FunctionProperties<MVideoCaption> &
23 Pick<MVideoCaption, 'language'> &
24 Use<'Video', MVideoUUID>
diff --git a/server/typings/models/video/video-change-ownership.ts b/server/typings/models/video/video-change-ownership.ts
index 0410115c6..72634cdb2 100644
--- a/server/typings/models/video/video-change-ownership.ts
+++ b/server/typings/models/video/video-change-ownership.ts
@@ -1,6 +1,6 @@
1import { VideoChangeOwnershipModel } from '@server/models/video/video-change-ownership' 1import { VideoChangeOwnershipModel } from '@server/models/video/video-change-ownership'
2import { PickWith } from '@server/typings/utils' 2import { PickWith } from '@server/typings/utils'
3import { MAccountDefault, MVideoWithFileThumbnail } from '@server/typings/models' 3import { MAccountDefault, MAccountFormattable, MVideo, MVideoWithFileThumbnail } from '@server/typings/models'
4 4
5type Use<K extends keyof VideoChangeOwnershipModel, M> = PickWith<VideoChangeOwnershipModel, K, M> 5type Use<K extends keyof VideoChangeOwnershipModel, M> = PickWith<VideoChangeOwnershipModel, K, M>
6 6
@@ -12,3 +12,12 @@ export type MVideoChangeOwnershipFull = MVideoChangeOwnership &
12 Use<'Initiator', MAccountDefault> & 12 Use<'Initiator', MAccountDefault> &
13 Use<'NextOwner', MAccountDefault> & 13 Use<'NextOwner', MAccountDefault> &
14 Use<'Video', MVideoWithFileThumbnail> 14 Use<'Video', MVideoWithFileThumbnail>
15
16// ############################################################################
17
18// Format for API or AP object
19
20export type MVideoChangeOwnershipFormattable = Pick<MVideoChangeOwnership, 'id' | 'status' | 'createdAt'> &
21 Use<'Initiator', MAccountFormattable> &
22 Use<'NextOwner', MAccountFormattable> &
23 Use<'Video', Pick<MVideo, 'id' | 'uuid' | 'url' | 'name'>>
diff --git a/server/typings/models/video/video-channels.ts b/server/typings/models/video/video-channels.ts
index b6506ed9f..2be7dd7ed 100644
--- a/server/typings/models/video/video-channels.ts
+++ b/server/typings/models/video/video-channels.ts
@@ -1,19 +1,23 @@
1import { PickWith } from '../../utils' 1import { FunctionProperties, PickWith, PickWithOpt } from '../../utils'
2import { VideoChannelModel } from '../../../models/video/video-channel' 2import { VideoChannelModel } from '../../../models/video/video-channel'
3import { 3import {
4 MAccountActor, 4 MAccountActor,
5 MAccountAPI, 5 MAccountAPI,
6 MAccountDefault, 6 MAccountDefault,
7 MAccountFormattable,
7 MAccountLight, 8 MAccountLight,
8 MAccountSummaryBlocks, 9 MAccountSummaryBlocks,
10 MAccountSummaryFormattable,
9 MAccountUserId, 11 MAccountUserId,
10 MActor, 12 MActor,
11 MActorAccountChannelId, 13 MActorAccountChannelId,
12 MActorAPI, 14 MActorAPI,
13 MActorDefault, 15 MActorDefault,
14 MActorDefaultLight, 16 MActorDefaultLight,
17 MActorFormattable,
15 MActorLight, 18 MActorLight,
16 MActorSummary 19 MActorSummary,
20 MActorSummaryFormattable
17} from '../account' 21} from '../account'
18import { MVideo } from './video' 22import { MVideo } from './video'
19 23
@@ -86,7 +90,8 @@ export type MChannelActorAccountDefaultVideos = MChannel &
86 90
87// For API 91// For API
88 92
89export type MChannelSummary = Pick<MChannel, 'id' | 'name' | 'description' | 'actorId'> & 93export type MChannelSummary = FunctionProperties<MChannel> &
94 Pick<MChannel, 'id' | 'name' | 'description' | 'actorId'> &
90 Use<'Actor', MActorSummary> 95 Use<'Actor', MActorSummary>
91 96
92export type MChannelSummaryAccount = MChannelSummary & 97export type MChannelSummaryAccount = MChannelSummary &
@@ -95,3 +100,19 @@ export type MChannelSummaryAccount = MChannelSummary &
95export type MChannelAPI = MChannel & 100export type MChannelAPI = MChannel &
96 Use<'Actor', MActorAPI> & 101 Use<'Actor', MActorAPI> &
97 Use<'Account', MAccountAPI> 102 Use<'Account', MAccountAPI>
103
104// ############################################################################
105
106// Format for API or AP object
107
108export type MChannelSummaryFormattable = FunctionProperties<MChannel> &
109 Pick<MChannel, 'id' | 'name'> &
110 Use<'Actor', MActorSummaryFormattable>
111
112export type MChannelAccountSummaryFormattable = MChannelSummaryFormattable &
113 Use<'Account', MAccountSummaryFormattable>
114
115export type MChannelFormattable = FunctionProperties<MChannel> &
116 Pick<MChannel, 'id' | 'name' | 'description' | 'createdAt' | 'updatedAt' | 'support'> &
117 Use<'Actor', MActorFormattable> &
118 PickWithOpt<VideoChannelModel, 'Account', MAccountFormattable>
diff --git a/server/typings/models/video/video-comment.ts b/server/typings/models/video/video-comment.ts
index 187461213..e8bccba0f 100644
--- a/server/typings/models/video/video-comment.ts
+++ b/server/typings/models/video/video-comment.ts
@@ -1,6 +1,6 @@
1import { VideoCommentModel } from '../../../models/video/video-comment' 1import { VideoCommentModel } from '../../../models/video/video-comment'
2import { PickWith } from '../../utils' 2import { PickWith } from '../../utils'
3import { MAccountDefault } from '../account' 3import { MAccountDefault, MAccountFormattable } from '../account'
4import { MVideoAccountLight, MVideoFeed, MVideoIdUrl } from './video' 4import { MVideoAccountLight, MVideoFeed, MVideoIdUrl } from './video'
5 5
6type Use<K extends keyof VideoCommentModel, M> = PickWith<VideoCommentModel, K, M> 6type Use<K extends keyof VideoCommentModel, M> = PickWith<VideoCommentModel, K, M>
@@ -8,6 +8,7 @@ type Use<K extends keyof VideoCommentModel, M> = PickWith<VideoCommentModel, K,
8// ############################################################################ 8// ############################################################################
9 9
10export type MComment = Omit<VideoCommentModel, 'OriginVideoComment' | 'InReplyToVideoComment' | 'Video' | 'Account'> 10export type MComment = Omit<VideoCommentModel, 'OriginVideoComment' | 'InReplyToVideoComment' | 'Video' | 'Account'>
11export type MCommentTotalReplies = MComment & { totalReplies?: number }
11export type MCommentId = Pick<MComment, 'id'> 12export type MCommentId = Pick<MComment, 'id'>
12 13
13// ############################################################################ 14// ############################################################################
@@ -41,3 +42,10 @@ export type MCommentOwnerVideoFeed = MCommentOwner &
41// ############################################################################ 42// ############################################################################
42 43
43export type MCommentAPI = MComment & { totalReplies: number } 44export type MCommentAPI = MComment & { totalReplies: number }
45
46// ############################################################################
47
48// Format for API or AP object
49
50export type MCommentFormattable = MCommentTotalReplies &
51 Use<'Account', MAccountFormattable>
diff --git a/server/typings/models/video/video-import.ts b/server/typings/models/video/video-import.ts
index ada723713..c6a1c5b66 100644
--- a/server/typings/models/video/video-import.ts
+++ b/server/typings/models/video/video-import.ts
@@ -1,6 +1,6 @@
1import { VideoImportModel } from '@server/models/video/video-import' 1import { VideoImportModel } from '@server/models/video/video-import'
2import { PickWith } from '@server/typings/utils' 2import { PickWith, PickWithOpt } from '@server/typings/utils'
3import { MUser, MVideo, MVideoAccountLight, MVideoTag, MVideoThumbnail, MVideoWithFile } from '@server/typings/models' 3import { MUser, MVideo, MVideoAccountLight, MVideoFormattable, MVideoTag, MVideoThumbnail, MVideoWithFile } from '@server/typings/models'
4 4
5type Use<K extends keyof VideoImportModel, M> = PickWith<VideoImportModel, K, M> 5type Use<K extends keyof VideoImportModel, M> = PickWith<VideoImportModel, K, M>
6 6
@@ -22,3 +22,10 @@ export type MVideoImportDefault = MVideoImport &
22export type MVideoImportDefaultFiles = MVideoImport & 22export type MVideoImportDefaultFiles = MVideoImport &
23 Use<'User', MUser> & 23 Use<'User', MUser> &
24 Use<'Video', VideoAssociation & MVideoWithFile> 24 Use<'Video', VideoAssociation & MVideoWithFile>
25
26// ############################################################################
27
28// Format for API or AP object
29
30export type MVideoImportFormattable = MVideoImport &
31 PickWithOpt<VideoImportModel, 'Video', MVideoFormattable & MVideoTag>
diff --git a/server/typings/models/video/video-playlist-element.ts b/server/typings/models/video/video-playlist-element.ts
index 5a039d7b1..1c256fd25 100644
--- a/server/typings/models/video/video-playlist-element.ts
+++ b/server/typings/models/video/video-playlist-element.ts
@@ -1,6 +1,6 @@
1import { VideoPlaylistElementModel } from '@server/models/video/video-playlist-element' 1import { VideoPlaylistElementModel } from '@server/models/video/video-playlist-element'
2import { PickWith } from '@server/typings/utils' 2import { PickWith } from '@server/typings/utils'
3import { MVideoPlaylistPrivacy, MVideoThumbnail, MVideoUrl } from '@server/typings/models' 3import { MVideoFormattable, MVideoPlaylistPrivacy, MVideoThumbnail, MVideoUrl } from '@server/typings/models'
4 4
5type Use<K extends keyof VideoPlaylistElementModel, M> = PickWith<VideoPlaylistElementModel, K, M> 5type Use<K extends keyof VideoPlaylistElementModel, M> = PickWith<VideoPlaylistElementModel, K, M>
6 6
@@ -23,6 +23,13 @@ export type MVideoPlaylistVideoThumbnail = MVideoPlaylistElement &
23 23
24// For API 24// For API
25 25
26export type MVideoPlaylistAP = MVideoPlaylistElement & 26export type MVideoPlaylistElementAP = MVideoPlaylistElement &
27 Use<'Video', MVideoUrl> & 27 Use<'Video', MVideoUrl> &
28 Use<'VideoPlaylist', MVideoPlaylistPrivacy> 28 Use<'VideoPlaylist', MVideoPlaylistPrivacy>
29
30// ############################################################################
31
32// Format for API or AP object
33
34export type MVideoPlaylistElementFormattable = MVideoPlaylistElement &
35 Use<'Video', MVideoFormattable>
diff --git a/server/typings/models/video/video-playlist.ts b/server/typings/models/video/video-playlist.ts
index 633818405..a926106c5 100644
--- a/server/typings/models/video/video-playlist.ts
+++ b/server/typings/models/video/video-playlist.ts
@@ -1,8 +1,8 @@
1import { VideoPlaylistModel } from '../../../models/video/video-playlist' 1import { VideoPlaylistModel } from '../../../models/video/video-playlist'
2import { PickWith } from '../../utils' 2import { PickWith } from '../../utils'
3import { MAccount, MAccountDefault, MAccountSummary } from '../account' 3import { MAccount, MAccountDefault, MAccountSummary, MAccountSummaryFormattable } from '../account'
4import { MThumbnail } from './thumbnail' 4import { MThumbnail } from './thumbnail'
5import { MChannelDefault, MChannelSummary } from './video-channels' 5import { MChannelDefault, MChannelSummary, MChannelSummaryFormattable } from './video-channels'
6import { MVideoPlaylistElementLight } from '@server/typings/models/video/video-playlist-element' 6import { MVideoPlaylistElementLight } from '@server/typings/models/video/video-playlist-element'
7 7
8type Use<K extends keyof VideoPlaylistModel, M> = PickWith<VideoPlaylistModel, K, M> 8type Use<K extends keyof VideoPlaylistModel, M> = PickWith<VideoPlaylistModel, K, M>
@@ -16,7 +16,7 @@ export type MVideoPlaylist = Omit<VideoPlaylistModel, 'OwnerAccount' | 'VideoCha
16export type MVideoPlaylistId = Pick<MVideoPlaylist, 'id'> 16export type MVideoPlaylistId = Pick<MVideoPlaylist, 'id'>
17export type MVideoPlaylistPrivacy = Pick<MVideoPlaylist, 'privacy'> 17export type MVideoPlaylistPrivacy = Pick<MVideoPlaylist, 'privacy'>
18export type MVideoPlaylistUUID = Pick<MVideoPlaylist, 'uuid'> 18export type MVideoPlaylistUUID = Pick<MVideoPlaylist, 'uuid'>
19export type MVideoPlaylistVideosLength = MVideoPlaylist & { videosLength: number } 19export type MVideoPlaylistVideosLength = MVideoPlaylist & { videosLength?: number }
20 20
21// ############################################################################ 21// ############################################################################
22 22
@@ -78,3 +78,11 @@ export type MVideoPlaylistFullSummary = MVideoPlaylist &
78 Use<'Thumbnail', MThumbnail> & 78 Use<'Thumbnail', MThumbnail> &
79 Use<'OwnerAccount', MAccountSummary> & 79 Use<'OwnerAccount', MAccountSummary> &
80 Use<'VideoChannel', MChannelSummary> 80 Use<'VideoChannel', MChannelSummary>
81
82// ############################################################################
83
84// Format for API or AP object
85
86export type MVideoPlaylistFormattable = MVideoPlaylistVideosLength &
87 Use<'OwnerAccount', MAccountSummaryFormattable> &
88 Use<'VideoChannel', MChannelSummaryFormattable>
diff --git a/server/typings/models/video/video-rate.ts b/server/typings/models/video/video-rate.ts
index fc9329993..2ff8a625b 100644
--- a/server/typings/models/video/video-rate.ts
+++ b/server/typings/models/video/video-rate.ts
@@ -1,6 +1,6 @@
1import { AccountVideoRateModel } from '@server/models/account/account-video-rate' 1import { AccountVideoRateModel } from '@server/models/account/account-video-rate'
2import { PickWith } from '@server/typings/utils' 2import { PickWith } from '@server/typings/utils'
3import { MAccountAudience, MAccountUrl, MVideo } from '..' 3import { MAccountAudience, MAccountUrl, MVideo, MVideoFormattable } from '..'
4 4
5type Use<K extends keyof AccountVideoRateModel, M> = PickWith<AccountVideoRateModel, K, M> 5type Use<K extends keyof AccountVideoRateModel, M> = PickWith<AccountVideoRateModel, K, M>
6 6
@@ -14,3 +14,10 @@ export type MAccountVideoRateAccountUrl = MAccountVideoRate &
14export type MAccountVideoRateAccountVideo = MAccountVideoRate & 14export type MAccountVideoRateAccountVideo = MAccountVideoRate &
15 Use<'Account', MAccountAudience> & 15 Use<'Account', MAccountAudience> &
16 Use<'Video', MVideo> 16 Use<'Video', MVideo>
17
18// ############################################################################
19
20// Format for API or AP object
21
22export type MAccountVideoRateFormattable = Pick<MAccountVideoRate, 'type'> &
23 Use<'Video', MVideoFormattable>
diff --git a/server/typings/models/video/video.ts b/server/typings/models/video/video.ts
index 914eb7f57..bc6d56607 100644
--- a/server/typings/models/video/video.ts
+++ b/server/typings/models/video/video.ts
@@ -1,12 +1,19 @@
1import { VideoModel } from '../../../models/video/video' 1import { VideoModel } from '../../../models/video/video'
2import { PickWith, PickWithOpt } from '../../utils' 2import { PickWith, PickWithOpt } from '../../utils'
3import { MChannelAccountDefault, MChannelAccountLight, MChannelActor, MChannelUserId } from './video-channels' 3import {
4 MChannelAccountDefault,
5 MChannelAccountLight,
6 MChannelAccountSummaryFormattable,
7 MChannelActor,
8 MChannelFormattable,
9 MChannelUserId
10} from './video-channels'
4import { MTag } from './tag' 11import { MTag } from './tag'
5import { MVideoCaptionLanguage } from './video-caption' 12import { MVideoCaptionLanguage } from './video-caption'
6import { MStreamingPlaylist, MStreamingPlaylistRedundancies } from './video-streaming-playlist' 13import { MStreamingPlaylist, MStreamingPlaylistRedundancies } from './video-streaming-playlist'
7import { MVideoFile, MVideoFileRedundanciesOpt } from './video-file' 14import { MVideoFile, MVideoFileRedundanciesOpt } from './video-file'
8import { MThumbnail } from './thumbnail' 15import { MThumbnail } from './thumbnail'
9import { MVideoBlacklistLight, MVideoBlacklistUnfederated } from './video-blacklist' 16import { MVideoBlacklist, MVideoBlacklistLight, MVideoBlacklistUnfederated } from './video-blacklist'
10import { MScheduleVideoUpdate } from './schedule-video-update' 17import { MScheduleVideoUpdate } from './schedule-video-update'
11import { MUserVideoHistoryTime } from '../user/user-video-history' 18import { MUserVideoHistoryTime } from '../user/user-video-history'
12 19
@@ -144,3 +151,19 @@ export type MVideoForUser = MVideo &
144 Use<'ScheduleVideoUpdate', MScheduleVideoUpdate> & 151 Use<'ScheduleVideoUpdate', MScheduleVideoUpdate> &
145 Use<'VideoBlacklist', MVideoBlacklistLight> & 152 Use<'VideoBlacklist', MVideoBlacklistLight> &
146 Use<'Thumbnails', MThumbnail[]> 153 Use<'Thumbnails', MThumbnail[]>
154
155// ############################################################################
156
157// Format for API or AP object
158
159export type MVideoFormattable = MVideo &
160 PickWithOpt<VideoModel, 'UserVideoHistories', MUserVideoHistoryTime[]> &
161 Use<'VideoChannel', MChannelAccountSummaryFormattable> &
162 PickWithOpt<VideoModel, 'ScheduleVideoUpdate', Pick<MScheduleVideoUpdate, 'updateAt' | 'privacy'>> &
163 PickWithOpt<VideoModel, 'VideoBlacklist', Pick<MVideoBlacklist, 'reason'>>
164
165export type MVideoFormattableDetails = MVideoFormattable &
166 Use<'VideoChannel', MChannelFormattable> &
167 Use<'Tags', MTag[]> &
168 Use<'VideoStreamingPlaylists', MStreamingPlaylistRedundancies[]> &
169 Use<'VideoFiles', MVideoFileRedundanciesOpt[]>
diff --git a/server/typings/utils.ts b/server/typings/utils.ts
index ed0fca3d1..4b5cf4d7e 100644
--- a/server/typings/utils.ts
+++ b/server/typings/utils.ts
@@ -4,8 +4,6 @@ export type FunctionPropertyNames<T> = {
4 4
5export type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>> 5export type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>
6 6
7export type ValueOf <T, KT extends keyof T> = T[KT]
8
9export type PickWith<T, KT extends keyof T, V> = { 7export type PickWith<T, KT extends keyof T, V> = {
10 [P in KT]: T[P] extends V ? V : never 8 [P in KT]: T[P] extends V ? V : never
11} 9}