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) { videoQuota: body.videoQuota, videoQuotaDaily: body.videoQuotaDaily, adminFlags: body.adminFlags || UserAdminFlag.NONE - }) + }) as MUser const { user, account } = await createUserAccountAndChannelAndPlaylist({ userToCreate: userToCreate }) 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' import { UserVideoQuota } from '../../../../shared/models/users/user-video-quota.model' import { updateAvatarValidator } from '../../../middlewares/validators/avatar' import { updateActorAvatarFile } from '../../../lib/avatar' -import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '../../../helpers/audit-logger' import { VideoImportModel } from '../../../models/video/video-import' import { AccountModel } from '../../../models/account/account' import { CONFIG } from '../../../initializers/config' import { sequelizeTypescript } from '../../../initializers/database' import { sendVerifyUserEmail } from '../../../lib/user' -const auditLogger = auditLoggerFactory('users-me') - const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.TMP_DIR }) const meRouter = express.Router() @@ -165,8 +162,6 @@ async function deleteMe (req: express.Request, res: express.Response) { await user.destroy() - auditLogger.delete(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON({}))) - return res.sendStatus(204) } @@ -175,7 +170,6 @@ async function updateMe (req: express.Request, res: express.Response) { let sendVerificationEmail = false const user = res.locals.oauth.token.user - const oldUserAuditView = new UserAuditView(user.toFormattedJSON({})) if (body.password !== undefined) user.password = body.password if (body.nsfwPolicy !== undefined) user.nsfwPolicy = body.nsfwPolicy @@ -204,8 +198,6 @@ async function updateMe (req: express.Request, res: express.Response) { await userAccount.save({ transaction: t }) await sendUpdateActor(userAccount, t) - - auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON({})), oldUserAuditView) }) if (sendVerificationEmail === true) { @@ -218,13 +210,10 @@ async function updateMe (req: express.Request, res: express.Response) { async function updateMyAvatar (req: express.Request, res: express.Response) { const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ] const user = res.locals.oauth.token.user - const oldUserAuditView = new UserAuditView(user.toFormattedJSON({})) const userAccount = await AccountModel.load(user.Account.id) const avatar = await updateActorAvatarFile(avatarPhysicalFile, userAccount) - auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON({})), oldUserAuditView) - return res.json({ avatar: avatar.toFormattedJSON() }) } 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' import { videoChannelsNameWithHostValidator, videosSortValidator } from '../../middlewares/validators' import { sendUpdateActor } from '../../lib/activitypub/send' import { VideoChannelCreate, VideoChannelUpdate } from '../../../shared' -import { createVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel' +import { createLocalVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel' import { buildNSFWFilter, createReqFiles, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils' import { setAsyncActorKeys } from '../../lib/activitypub' import { AccountModel } from '../../models/account/account' @@ -139,7 +139,7 @@ async function addVideoChannel (req: express.Request, res: express.Response) { const videoChannelCreated = await sequelizeTypescript.transaction(async t => { const account = await AccountModel.load(res.locals.oauth.token.User.Account.id, t) - return createVideoChannel(videoChannelInfo, account, t) + return createLocalVideoChannel(videoChannelInfo, account, t) }) 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 @@ import * as express from 'express' import * as magnetUtil from 'magnet-uri' -import 'multer' import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger' import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoImportAddValidator } from '../../../middlewares' import { MIMETYPES } from '../../../initializers/constants' @@ -28,11 +27,12 @@ import { MChannelAccountDefault, MThumbnail, MUser, + MVideoAccountDefault, MVideoTag, MVideoThumbnailAccountDefault, MVideoWithBlacklistLight } from '@server/typings/models' -import { MVideoImport, MVideoImportVideo } from '@server/typings/models/video/video-import' +import { MVideoImport, MVideoImportFormattable } from '@server/typings/models/video/video-import' const auditLogger = auditLoggerFactory('video-imports') const videoImportsRouter = express.Router() @@ -238,14 +238,14 @@ function insertIntoDB (parameters: { tags: string[], videoImportAttributes: Partial, user: MUser -}): Bluebird { +}): Bluebird { const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters return sequelizeTypescript.transaction(async t => { const sequelizeOptions = { transaction: t } // Save video object in database - const videoCreated = await video.save(sequelizeOptions) as (MVideoThumbnailAccountDefault & MVideoWithBlacklistLight & MVideoTag) + const videoCreated = await video.save(sequelizeOptions) as (MVideoAccountDefault & MVideoWithBlacklistLight & MVideoTag) videoCreated.VideoChannel = videoChannel if (thumbnailModel) await videoCreated.addAndSaveThumbnail(thumbnailModel, t) @@ -274,7 +274,7 @@ function insertIntoDB (parameters: { const videoImport = await VideoImportModel.create( Object.assign({ videoId: videoCreated.id }, videoImportAttributes), sequelizeOptions - ) as MVideoImportVideo + ) as MVideoImportFormattable videoImport.Video = videoCreated 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' import { CONFIG } from '../initializers/config' import * as srt2vtt from 'srt-to-vtt' import { createReadStream, createWriteStream, move, remove } from 'fs-extra' -import { MVideoCaption } from '@server/typings/models' +import { MVideoCaptionFormattable } from '@server/typings/models' -async function moveAndProcessCaptionFile (physicalFile: { filename: string, path: string }, videoCaption: MVideoCaption) { +async function moveAndProcessCaptionFile (physicalFile: { filename: string, path: string }, videoCaption: MVideoCaptionFormattable) { const videoCaptionsDir = CONFIG.STORAGE.CAPTIONS_DIR const destination = join(videoCaptionsDir, videoCaption.getCaptionName()) 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 { } from '../../typings/models' // Set account keys, this could be long so process after the account creation and do not block the client -function setAsyncActorKeys (actor: MActor) { +function setAsyncActorKeys (actor: T) { return createPrivateAndPublicKeys() .then(({ publicKey, privateKey }) => { actor.publicKey = publicKey @@ -148,7 +148,7 @@ function buildActorInstance (type: ActivityPubActorType, url: string, preferredU sharedInboxUrl: WEBSERVER.URL + '/inbox', followersUrl: url + '/followers', followingUrl: url + '/following' - }) + }) as MActor } async 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' import { ActivityPubActorType } from '../../shared/models/activitypub' import { SERVER_ACTOR_NAME, WEBSERVER } from '../initializers/constants' import { AccountModel } from '../models/account/account' -import { UserModel } from '../models/account/user' import { buildActorInstance, getAccountActivityPubUrl, setAsyncActorKeys } from './activitypub' -import { createVideoChannel } from './video-channel' +import { createLocalVideoChannel } from './video-channel' import { ActorModel } from '../models/activitypub/actor' import { UserNotificationSettingModel } from '../models/account/user-notification-setting' import { UserNotificationSetting, UserNotificationSettingValue } from '../../shared/models/users' @@ -13,17 +12,17 @@ import { sequelizeTypescript } from '../initializers/database' import { Transaction } from 'sequelize/types' import { Redis } from './redis' import { Emailer } from './emailer' -import { MAccountActor, MActor, MChannelActor } from '../typings/models' -import { MUser, MUserId, MUserNotifSettingAccount } from '../typings/models/user' +import { MAccountDefault, MActorDefault, MChannelActor } from '../typings/models' +import { MUser, MUserDefault, MUserId } from '../typings/models/user' type ChannelNames = { name: string, displayName: string } async function createUserAccountAndChannelAndPlaylist (parameters: { - userToCreate: UserModel, + userToCreate: MUser, userDisplayName?: string, channelNames?: ChannelNames, validateUser?: boolean -}): Promise<{ user: MUserNotifSettingAccount, account: MAccountActor, videoChannel: MChannelActor }> { +}): Promise<{ user: MUserDefault, account: MAccountDefault, videoChannel: MChannelActor }> { const { userToCreate, userDisplayName, channelNames, validateUser = true } = parameters const { user, account, videoChannel } = await sequelizeTypescript.transaction(async t => { @@ -32,7 +31,7 @@ async function createUserAccountAndChannelAndPlaylist (parameters: { validate: validateUser } - const userCreated: MUserNotifSettingAccount = await userToCreate.save(userOptions) + const userCreated: MUserDefault = await userToCreate.save(userOptions) userCreated.NotificationSetting = await createDefaultUserNotificationSettings(userCreated, t) const accountCreated = await createLocalAccountWithoutKeys({ @@ -45,7 +44,7 @@ async function createUserAccountAndChannelAndPlaylist (parameters: { userCreated.Account = accountCreated const channelAttributes = await buildChannelAttributes(userCreated, channelNames) - const videoChannel = await createVideoChannel(channelAttributes, accountCreated, t) + const videoChannel = await createLocalVideoChannel(channelAttributes, accountCreated, t) const videoPlaylist = await createWatchLaterPlaylist(accountCreated, t) @@ -75,7 +74,7 @@ async function createLocalAccountWithoutKeys (parameters: { const url = getAccountActivityPubUrl(name) const actorInstance = buildActorInstance(type, url, name) - const actorInstanceCreated: MActor = await actorInstance.save({ transaction: t }) + const actorInstanceCreated: MActorDefault = await actorInstance.save({ transaction: t }) const accountInstance = new AccountModel({ name: displayName || name, @@ -84,7 +83,7 @@ async function createLocalAccountWithoutKeys (parameters: { actorId: actorInstanceCreated.id }) - const accountInstanceCreated: MAccountActor = await accountInstance.save({ transaction: t }) + const accountInstanceCreated: MAccountDefault = await accountInstance.save({ transaction: t }) accountInstanceCreated.Actor = actorInstanceCreated 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' import { VideoChannelModel } from '../models/video/video-channel' import { buildActorInstance, federateVideoIfNeeded, getVideoChannelActivityPubUrl } from './activitypub' import { VideoModel } from '../models/video/video' -import { MAccountId, MChannelActor, MChannelId } from '../typings/models' +import { MAccountId, MChannelDefault, MChannelId } from '../typings/models' -type CustomVideoChannelModelAccount = MChannelActor & +type CustomVideoChannelModelAccount = MChannelDefault & { Account?: T } -async function createVideoChannel ( +async function createLocalVideoChannel ( videoChannelInfo: VideoChannelCreate, account: T, t: Sequelize.Transaction @@ -31,7 +31,7 @@ async function createVideoChannel ( const videoChannel = new VideoChannelModel(videoChannelData) const options = { transaction: t } - const videoChannelCreated: CustomVideoChannelModelAccount = await videoChannel.save(options) as MChannelActor + const videoChannelCreated: CustomVideoChannelModelAccount = await videoChannel.save(options) as MChannelDefault // Do not forget to add Account/Actor information to the created video channel videoChannelCreated.Account = account @@ -54,6 +54,6 @@ async function federateAllVideosOfChannel (videoChannel: MChannelId) { // --------------------------------------------------------------------------- export { - createVideoChannel, + createLocalVideoChannel, federateAllVideosOfChannel } 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' import { AccountBlock } from '../../../shared/models/blocklist' import { Op } from 'sequelize' import * as Bluebird from 'bluebird' -import { MAccountBlocklist, MAccountBlocklistAccounts } from '@server/typings/models' +import { MAccountBlocklist, MAccountBlocklistAccounts, MAccountBlocklistFormattable } from '@server/typings/models' enum ScopeNames { WITH_ACCOUNTS = 'WITH_ACCOUNTS' @@ -134,7 +134,7 @@ export class AccountBlocklistModel extends Model { }) } - toFormattedJSON (): AccountBlock { + toFormattedJSON (this: MAccountBlocklistFormattable): AccountBlock { return { byAccount: this.ByAccount.toFormattedJSON(), 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 import { AccountVideoRate } from '../../../shared' import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from '../video/video-channel' import * as Bluebird from 'bluebird' -import { MAccountVideoRate, MAccountVideoRateAccountUrl, MAccountVideoRateAccountVideo } from '@server/typings/models/video/video-rate' +import { + MAccountVideoRate, + MAccountVideoRateAccountUrl, + MAccountVideoRateAccountVideo, + MAccountVideoRateFormattable +} from '@server/typings/models/video/video-rate' /* Account rates per video. @@ -248,7 +253,7 @@ export class AccountVideoRateModel extends Model { }) } - toFormattedJSON (): AccountVideoRate { + toFormattedJSON (this: MAccountVideoRateFormattable): AccountVideoRate { return { video: this.Video.toFormattedJSON(), 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 import { AccountBlocklistModel } from './account-blocklist' import { ServerBlocklistModel } from '../server/server-blocklist' import { ActorFollowModel } from '../activitypub/actor-follow' -import { MAccountActor, MAccountDefault } from '../../typings/models' +import { MAccountActor, MAccountDefault, MAccountSummaryFormattable, MAccountFormattable } from '../../typings/models' import * as Bluebird from 'bluebird' export enum ScopeNames { @@ -353,7 +353,7 @@ export class AccountModel extends Model { .findAll(query) } - toFormattedJSON (): Account { + toFormattedJSON (this: MAccountFormattable): Account { const actor = this.Actor.toFormattedJSON() const account = { id: this.id, @@ -367,8 +367,8 @@ export class AccountModel extends Model { return Object.assign(actor, account) } - toFormattedSummaryJSON (): AccountSummary { - const actor = this.Actor.toFormattedJSON() + toFormattedSummaryJSON (this: MAccountSummaryFormattable): AccountSummary { + const actor = this.Actor.toFormattedSummaryJSON() return { 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' import { isUserNotificationSettingValid } from '../../helpers/custom-validators/user-notifications' import { UserNotificationSetting, UserNotificationSettingValue } from '../../../shared/models/users/user-notification-setting.model' import { clearCacheByUserId } from '../../lib/oauth-model' +import { MNotificationSettingFormattable } from '@server/typings/models' @Table({ tableName: 'userNotificationSetting', @@ -152,7 +153,7 @@ export class UserNotificationSettingModel extends Model { return comparePassword(password, this.password) } - toFormattedJSON (parameters: { withAdminFlags?: boolean } = {}): User { + toSummaryJSON + + toFormattedJSON (this: MUserFormattable, parameters: { withAdminFlags?: boolean } = {}): User { const videoQuotaUsed = this.get('videoQuotaUsed') const videoQuotaUsedDaily = this.get('videoQuotaUsedDaily') 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 { MActorFollowActorsDefault, MActorFollowActorsDefaultSubscription, MActorFollowFollowingHost, + MActorFollowFormattable, MActorFollowSubscriptions } from '@server/typings/models' @@ -580,7 +581,7 @@ export class ActorFollowModel extends Model { return ActorFollowModel.findAll(query) } - toFormattedJSON (): ActorFollow { + toFormattedJSON (this: MActorFollowFormattable): ActorFollow { const follower = this.ActorFollower.toFormattedJSON() const following = this.ActorFollowing.toFormattedJSON() 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' import { VideoChannelModel } from '../video/video-channel' import { ActorFollowModel } from './actor-follow' import { VideoModel } from '../video/video' -import { MActor, MActorAccountChannelId, MActorFull } from '../../typings/models' +import { + MActor, + MActorAccountChannelId, + MActorFormattable, + MActorFull, MActorHost, + MActorServer, + MActorSummaryFormattable, + MServerHost, + MActorRedundancyAllowed +} from '../../typings/models' import * as Bluebird from 'bluebird' enum ScopeNames { @@ -393,24 +402,31 @@ export class ActorModel extends Model { }) } - toFormattedJSON () { + toFormattedSummaryJSON (this: MActorSummaryFormattable) { let avatar: Avatar = null if (this.Avatar) { avatar = this.Avatar.toFormattedJSON() } return { - id: this.id, url: this.url, name: this.preferredUsername, host: this.getHost(), + avatar + } + } + + toFormattedJSON (this: MActorFormattable) { + const base = this.toFormattedSummaryJSON() + + return Object.assign(base, { + id: this.id, hostRedundancyAllowed: this.getRedundancyAllowed(), followingCount: this.followingCount, followersCount: this.followersCount, - avatar, createdAt: this.createdAt, updatedAt: this.updatedAt - } + }) } toActivityPubObject (name: string, type: 'Account' | 'Application' | 'VideoChannel') { @@ -500,7 +516,7 @@ export class ActorModel extends Model { return this.serverId === null } - getWebfingerUrl () { + getWebfingerUrl (this: MActorServer) { return 'acct:' + this.preferredUsername + '@' + this.getHost() } @@ -508,11 +524,11 @@ export class ActorModel extends Model { return this.Server ? `${this.preferredUsername}@${this.Server.host}` : this.preferredUsername } - getHost () { + getHost (this: MActorHost) { return this.Server ? this.Server.host : WEBSERVER.HOST } - getRedundancyAllowed () { + getRedundancyAllowed (this: MActorRedundancyAllowed) { return this.Server ? this.Server.redundancyAllowed : false } 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' import { CONFIG } from '../../initializers/config' import { throwIfNotValid } from '../utils' import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' +import { MAvatarFormattable } from '@server/typings/models' @Table({ tableName: 'avatar', @@ -57,7 +58,7 @@ export class AvatarModel extends Model { return AvatarModel.findOne(query) } - toFormattedJSON (): Avatar { + toFormattedJSON (this: MAvatarFormattable): Avatar { return { path: this.getStaticPath(), 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 import { FindAndCountOptions, json } from 'sequelize' import { RegisterServerSettingOptions } from '../../../shared/models/plugins/register-server-setting.model' import * as Bluebird from 'bluebird' -import { MPlugin } from '@server/typings/models' +import { MPlugin, MPluginFormattable } from '@server/typings/models' @DefaultScope(() => ({ attributes: { @@ -253,7 +253,7 @@ export class PluginModel extends Model { return result } - toFormattedJSON (): PeerTubePlugin { + toFormattedJSON (this: MPluginFormattable): PeerTubePlugin { return { name: this.name, 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' import { ServerBlock } from '../../../shared/models/blocklist' import { getSort } from '../utils' import * as Bluebird from 'bluebird' -import { MServerBlocklist, MServerBlocklistAccountServer } from '@server/typings/models' +import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/typings/models' enum ScopeNames { WITH_ACCOUNT = 'WITH_ACCOUNT', @@ -112,7 +112,7 @@ export class ServerBlocklistModel extends Model { }) } - toFormattedJSON (): ServerBlock { + toFormattedJSON (this: MServerBlocklistFormattable): ServerBlock { return { byAccount: this.ByAccount.toFormattedJSON(), 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' import { throwIfNotValid } from '../utils' import { ServerBlocklistModel } from './server-blocklist' import * as Bluebird from 'bluebird' -import { MServer } from '@server/typings/models/server' +import { MServer, MServerFormattable } from '@server/typings/models/server' @Table({ tableName: 'server', @@ -65,7 +65,7 @@ export class ServerModel extends Model { return this.BlockedByAccounts && this.BlockedByAccounts.length !== 0 } - toFormattedJSON () { + toFormattedJSON (this: MServerFormattable) { return { host: this.host } 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 import { ScopeNames as VideoScopeNames, VideoModel } from './video' import { VideoPrivacy } from '../../../shared/models/videos' import { Op, Transaction } from 'sequelize' +import { MScheduleVideoUpdateFormattable } from '@server/typings/models' @Table({ tableName: 'scheduleVideoUpdate', @@ -96,7 +97,7 @@ export class ScheduleVideoUpdateModel extends Model { return ScheduleVideoUpdateModel.destroy(query) } - toFormattedJSON () { + toFormattedJSON (this: MScheduleVideoUpdateFormattable) { return { updateAt: this.updateAt, 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' import { VideoModel } from './video' import { VideoAbuseState } from '../../../shared' import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants' -import { MVideoAbuse, MVideoAbuseAccountVideo, MVideoAbuseVideo } from '../../typings/models' +import { MVideoAbuse, MVideoAbuseFormattable, MVideoAbuseVideo } from '../../typings/models' import * as Bluebird from 'bluebird' @Table({ @@ -108,7 +108,7 @@ export class VideoAbuseModel extends Model { }) } - toFormattedJSON (this: MVideoAbuseAccountVideo): VideoAbuse { + toFormattedJSON (this: MVideoAbuseFormattable): VideoAbuse { return { id: this.id, 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' import { FindOptions } from 'sequelize' import { ThumbnailModel } from './thumbnail' import * as Bluebird from 'bluebird' -import { MVideoBlacklist } from '@server/typings/models' +import { MVideoBlacklist, MVideoBlacklistFormattable } from '@server/typings/models' @Table({ tableName: 'videoBlacklist', @@ -111,7 +111,7 @@ export class VideoBlacklistModel extends Model { return VideoBlacklistModel.findOne(query) } - toFormattedJSON (): VideoBlacklist { + toFormattedJSON (this: MVideoBlacklistFormattable): VideoBlacklist { return { id: this.id, 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' import { remove } from 'fs-extra' import { CONFIG } from '../../initializers/config' import * as Bluebird from 'bluebird' -import { MVideoCaptionVideo } from '@server/typings/models' +import { MVideoCaptionFormattable, MVideoCaptionVideo } from '@server/typings/models' export enum ScopeNames { WITH_VIDEO_UUID_AND_REMOTE = 'WITH_VIDEO_UUID_AND_REMOTE' @@ -154,7 +154,7 @@ export class VideoCaptionModel extends Model { return this.Video.remote === false } - toFormattedJSON (): VideoCaption { + toFormattedJSON (this: MVideoCaptionFormattable): VideoCaption { return { language: { id: this.language, @@ -164,15 +164,15 @@ export class VideoCaptionModel extends Model { } } - getCaptionStaticPath () { + getCaptionStaticPath (this: MVideoCaptionFormattable) { return join(LAZY_STATIC_PATHS.VIDEO_CAPTIONS, this.getCaptionName()) } - getCaptionName () { + getCaptionName (this: MVideoCaptionFormattable) { return `${this.Video.uuid}-${this.language}.vtt` } - removeCaptionFile () { + removeCaptionFile (this: MVideoCaptionFormattable) { return remove(CONFIG.STORAGE.CAPTIONS_DIR + this.getCaptionName()) } } 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' import { ScopeNames as VideoScopeNames, VideoModel } from './video' import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '../../../shared/models/videos' import { getSort } from '../utils' -import { MVideoChangeOwnershipFull } from '@server/typings/models/video/video-change-ownership' +import { MVideoChangeOwnershipFormattable, MVideoChangeOwnershipFull } from '@server/typings/models/video/video-change-ownership' import * as Bluebird from 'bluebird' enum ScopeNames { @@ -119,7 +119,7 @@ export class VideoChangeOwnershipModel extends Model .findByPk(id) } - toFormattedJSON (): VideoChangeOwnership { + toFormattedJSON (this: MVideoChangeOwnershipFormattable): VideoChangeOwnership { return { id: this.id, 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' import { MChannelAccountDefault, MChannelActor, - MChannelActorAccountDefaultVideos + MChannelActorAccountDefaultVideos, MChannelSummaryFormattable, MChannelFormattable } from '../../typings/models/video' // 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 { .findByPk(id, options) } - toFormattedJSON (): VideoChannel { + toFormattedSummaryJSON (this: MChannelSummaryFormattable): VideoChannelSummary { + const actor = this.Actor.toFormattedSummaryJSON() + + return { + id: this.id, + name: actor.name, + displayName: this.getDisplayName(), + url: actor.url, + host: actor.host, + avatar: actor.avatar + } + } + + toFormattedJSON (this: MChannelFormattable): VideoChannel { const actor = this.Actor.toFormattedJSON() const videoChannel = { id: this.id, @@ -500,19 +513,6 @@ export class VideoChannelModel extends Model { return Object.assign(actor, videoChannel) } - toFormattedSummaryJSON (): VideoChannelSummary { - const actor = this.Actor.toFormattedJSON() - - return { - id: this.id, - name: actor.name, - displayName: this.getDisplayName(), - url: actor.url, - host: actor.host, - avatar: actor.avatar - } - } - toActivityPubObject (): ActivityPubActor { const obj = this.Actor.toActivityPubObject(this.name, 'VideoChannel') 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 import * as Bluebird from 'bluebird' import { MComment, + MCommentFormattable, MCommentId, MCommentOwner, MCommentOwnerReplyVideoLight, @@ -475,7 +476,7 @@ export class VideoCommentModel extends Model { return uniq(result) } - toFormattedJSON () { + toFormattedJSON (this: MCommentFormattable) { return { id: this.id, 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 { } from '../../lib/activitypub' import { isArray } from '../../helpers/custom-validators/misc' import { VideoStreamingPlaylist } from '../../../shared/models/videos/video-streaming-playlist.model' -import { MVideo, MVideoAP, MVideoDetails } from '../../typings/models' +import { MVideo, MVideoAP, MVideoFormattable, MVideoFormattableDetails } from '../../typings/models' import { MStreamingPlaylistRedundancies } from '../../typings/models/video/video-streaming-playlist' import { MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file' @@ -29,7 +29,7 @@ export type VideoFormattingJSONOptions = { blacklistInfo?: boolean } } -function videoModelToFormattedJSON (video: VideoModel, options?: VideoFormattingJSONOptions): Video { +function videoModelToFormattedJSON (video: MVideoFormattable, options?: VideoFormattingJSONOptions): Video { const userHistory = isArray(video.UserVideoHistories) ? video.UserVideoHistories[0] : undefined const videoObject: Video = { @@ -103,7 +103,7 @@ function videoModelToFormattedJSON (video: VideoModel, options?: VideoFormatting return videoObject } -function videoModelToFormattedDetailsJSON (video: MVideoDetails): VideoDetails { +function videoModelToFormattedDetailsJSON (video: MVideoFormattableDetails): VideoDetails { const formattedJson = video.toFormattedJSON({ additionalAttributes: { 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' import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos' import { UserModel } from '../account/user' import * as Bluebird from 'bluebird' -import { MVideoImportDefault } from '@server/typings/models/video/video-import' +import { MVideoImportDefault, MVideoImportFormattable } from '@server/typings/models/video/video-import' @DefaultScope(() => ({ include: [ @@ -154,7 +154,7 @@ export class VideoImportModel extends Model { return this.targetUrl || this.magnetUri || this.torrentName } - toFormattedJSON (): VideoImport { + toFormattedJSON (this: MVideoImportFormattable): VideoImport { const videoFormatOptions = { completeDescription: true, 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' import { PlaylistElementObject } from '../../../shared/models/activitypub/objects/playlist-element-object' import * as validator from 'validator' import { AggregateOptions, Op, ScopeOptions, Sequelize, Transaction } from 'sequelize' -import { UserModel } from '../account/user' import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../shared/models/videos/playlist/video-playlist-element.model' import { AccountModel } from '../account/account' import { VideoPrivacy } from '../../../shared/models/videos' import * as Bluebird from 'bluebird' -import { MVideoPlaylistAP, MVideoPlaylistElement, MVideoPlaylistVideoThumbnail } from '@server/typings/models/video/video-playlist-element' +import { + MVideoPlaylistElement, + MVideoPlaylistElementAP, + MVideoPlaylistElementFormattable, + MVideoPlaylistVideoThumbnail +} from '@server/typings/models/video/video-playlist-element' import { MUserAccountId } from '@server/typings/models' @Table({ @@ -180,7 +184,7 @@ export class VideoPlaylistElementModel extends Model return VideoPlaylistElementModel.findByPk(playlistElementId) } - static loadByPlaylistAndVideoForAP (playlistId: number | string, videoId: number | string): Bluebird { + static loadByPlaylistAndVideoForAP (playlistId: number | string, videoId: number | string): Bluebird { const playlistWhere = validator.isUUID('' + playlistId) ? { uuid: playlistId } : { id: playlistId } const videoWhere = validator.isUUID('' + videoId) ? { uuid: videoId } : { id: videoId } @@ -293,7 +297,7 @@ export class VideoPlaylistElementModel extends Model return VideoPlaylistElementModel.increment({ position: by }, query) } - getType (displayNSFW?: boolean, accountId?: number) { + getType (this: MVideoPlaylistElementFormattable, displayNSFW?: boolean, accountId?: number) { const video = this.Video if (!video) return VideoPlaylistElementType.DELETED @@ -309,14 +313,17 @@ export class VideoPlaylistElementModel extends Model return VideoPlaylistElementType.REGULAR } - getVideoElement (displayNSFW?: boolean, accountId?: number) { + getVideoElement (this: MVideoPlaylistElementFormattable, displayNSFW?: boolean, accountId?: number) { if (!this.Video) return null if (this.getType(displayNSFW, accountId) !== VideoPlaylistElementType.REGULAR) return null return this.Video.toFormattedJSON() } - toFormattedJSON (options: { displayNSFW?: boolean, accountId?: number } = {}): VideoPlaylistElement { + toFormattedJSON ( + this: MVideoPlaylistElementFormattable, + options: { displayNSFW?: boolean, accountId?: number } = {} + ): VideoPlaylistElement { return { id: this.id, 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 import * as Bluebird from 'bluebird' import { MVideoPlaylistAccountThumbnail, + MVideoPlaylistFormattable, MVideoPlaylistFull, MVideoPlaylistFullSummary, MVideoPlaylistIdWithElements @@ -479,7 +480,7 @@ export class VideoPlaylistModel extends Model { return isOutdated(this, ACTIVITY_PUB.VIDEO_PLAYLIST_REFRESH_INTERVAL) } - toFormattedJSON (): VideoPlaylist { + toFormattedJSON (this: MVideoPlaylistFormattable): VideoPlaylist { return { id: this.id, 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 { MVideoFullLight, MVideoIdThumbnail, MVideoThumbnail, - MVideoWithAllFiles, - MVideoWithRights + MVideoWithAllFiles, MVideoWithFile, + MVideoWithRights, + MVideoFormattable } from '../../typings/models' import { MVideoFile, MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file' import { MThumbnail } from '../../typings/models/video/thumbnail' @@ -1765,14 +1766,14 @@ export class VideoModel extends Model { this.VideoChannel.Account.isBlocked() } - getOriginalFile () { + getOriginalFile (this: T) { if (Array.isArray(this.VideoFiles) === false) return undefined // The original file is the file that have the higher resolution return maxBy(this.VideoFiles, file => file.resolution) } - getFile (resolution: number) { + getFile (this: T, resolution: number) { if (Array.isArray(this.VideoFiles) === false) return undefined return this.VideoFiles.find(f => f.resolution === resolution) @@ -1878,7 +1879,7 @@ export class VideoModel extends Model { return join(LAZY_STATIC_PATHS.PREVIEWS, preview.filename) } - toFormattedJSON (options?: VideoFormattingJSONOptions): Video { + toFormattedJSON (this: T, options?: VideoFormattingJSONOptions): Video { return videoModelToFormattedJSON(this, options) } 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 @@ import { AccountBlocklistModel } from '../../../models/account/account-blocklist' import { PickWith } from '../../utils' -import { MAccountDefault } from './account' +import { MAccountDefault, MAccountFormattable } from './account' type Use = PickWith @@ -15,3 +15,11 @@ export type MAccountBlocklistId = Pick export type MAccountBlocklistAccounts = MAccountBlocklist & Use<'ByAccount', MAccountDefault> & Use<'BlockedAccount', MAccountDefault> + +// ############################################################################ + +// Format for API or AP object + +export type MAccountBlocklistFormattable = Pick & + Use<'ByAccount', MAccountFormattable> & + 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 { MActorId, MActorServer, MActorSummary, - MActorUrl + MActorSummaryFormattable, + MActorUrl, + MActorFormattable } from './actor' -import { PickWith } from '../../utils' +import { FunctionProperties, PickWith } from '../../utils' import { MAccountBlocklistId } from './account-blocklist' import { MChannelDefault } from '@server/typings/models' @@ -67,7 +69,8 @@ export type MAccountServer = MAccount & // For API -export type MAccountSummary = Pick & +export type MAccountSummary = FunctionProperties & + Pick & Use<'Actor', MActorSummary> export type MAccountSummaryBlocks = MAccountSummary & @@ -75,3 +78,15 @@ export type MAccountSummaryBlocks = MAccountSummary & export type MAccountAPI = MAccount & Use<'Actor', MActorAPI> + +// ############################################################################ + +// Format for API or AP object + +export type MAccountSummaryFormattable = FunctionProperties & + Pick & + Use<'Actor', MActorSummaryFormattable> + +export type MAccountFormattable = FunctionProperties & + Pick & + 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 { MActor, MActorAccount, MActorAccountChannel, - MActorChannel, MActorChannelAccountActor, MActorDefault, + MActorFormattable, MActorHost, MActorUsername } from './actor' import { PickWith } from '../../utils' import { ActorModel } from '@server/models/activitypub/actor' +import { MChannelDefault } from '@server/typings/models' type Use = PickWith @@ -43,9 +44,12 @@ export type MActorFollowFull = MActorFollow & // For subscriptions +type SubscriptionFollowing = MActorDefault & + PickWith + export type MActorFollowActorsDefaultSubscription = MActorFollow & Use<'ActorFollower', MActorDefault> & - Use<'ActorFollowing', MActorDefault & MActorChannel> + Use<'ActorFollowing', SubscriptionFollowing> export type MActorFollowFollowingFullFollowerAccount = MActorFollow & Use<'ActorFollower', MActorAccount> & @@ -53,3 +57,11 @@ export type MActorFollowFollowingFullFollowerAccount = MActorFollow & export type MActorFollowSubscriptions = MActorFollow & Use<'ActorFollowing', MActorChannelAccountActor> + +// ############################################################################ + +// Format for API or AP object + +export type MActorFollowFormattable = Pick & + Use<'ActorFollower', MActorFormattable> & + 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 @@ import { ActorModel } from '../../../models/activitypub/actor' -import { PickWith } from '../../utils' +import { FunctionProperties, PickWith } from '../../utils' import { MAccount, MAccountDefault, MAccountId, MAccountIdActor } from './account' -import { MServer, MServerHost, MServerHostBlocks } from '../server' -import { MAvatar } from './avatar' +import { MServer, MServerHost, MServerHostBlocks, MServerRedundancyAllowed } from '../server' +import { MAvatar, MAvatarFormattable } from './avatar' import { MChannel, MChannelAccountActor, MChannelAccountDefault, MChannelId, MChannelIdActor } from '../video' type Use = PickWith @@ -29,6 +29,7 @@ export type MActorLight = Omit // Some association attributes export type MActorHost = Use<'Server', MServerHost> +export type MActorRedundancyAllowed = Use<'Server', MServerRedundancyAllowed> export type MActorDefaultLight = MActorLight & Use<'Server', MServerHost> & @@ -92,7 +93,8 @@ export type MActorFullActor = MActor & // API -export type MActorSummary = Pick & +export type MActorSummary = FunctionProperties & + Pick & Use<'Server', MServerHost> & Use<'Avatar', MAvatar> @@ -101,3 +103,16 @@ export type MActorSummaryBlocks = MActorSummary & export type MActorAPI = Omit + +// ############################################################################ + +// Format for API or AP object + +export type MActorSummaryFormattable = FunctionProperties & + Pick & + Use<'Server', MServerHost> & + Use<'Avatar', MAvatarFormattable> + +export type MActorFormattable = MActorSummaryFormattable & + Pick & + 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 @@ import { AvatarModel } from '../../../models/avatar/avatar' +import { FunctionProperties } from '@server/typings/utils' export type MAvatar = AvatarModel + +// ############################################################################ + +// Format for API or AP object + +export type MAvatarFormattable = FunctionProperties & + Pick 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 @@ import { PluginModel } from '@server/models/server/plugin' export type MPlugin = PluginModel + +// ############################################################################ + +// Format for API or AP object + +export type MPluginFormattable = Pick 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 @@ import { ServerBlocklistModel } from '@server/models/server/server-blocklist' import { PickWith } from '@server/typings/utils' -import { MAccountDefault, MServer } from '@server/typings/models' +import { MAccountDefault, MAccountFormattable, MServer, MServerFormattable } from '@server/typings/models' type Use = PickWith @@ -13,3 +13,11 @@ export type MServerBlocklist = Omit & Use<'BlockedServer', MServer> + +// ############################################################################ + +// Format for API or AP object + +export type MServerBlocklistFormattable = Pick & + Use<'ByAccount', MAccountFormattable> & + 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 @@ import { ServerModel } from '../../../models/server/server' -import { PickWith } from '../../utils' +import { FunctionProperties, PickWith } from '../../utils' import { MAccountBlocklistId } from '../account' type Use = PickWith @@ -11,6 +11,14 @@ export type MServer = Omit // ############################################################################ export type MServerHost = Pick +export type MServerRedundancyAllowed = Pick export type MServerHostBlocks = MServerHost & Use<'BlockedByAccounts', MAccountBlocklistId[]> + +// ############################################################################ + +// Format for API or AP object + +export type MServerFormattable = FunctionProperties & + Pick 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 @@ import { UserNotificationSettingModel } from '@server/models/account/user-notification-setting' export type MNotificationSetting = Omit + +// ############################################################################ + +// Format for API or AP object + +export 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 @@ import { UserModel } from '../../../models/account/user' -import { PickWith } from '../../utils' -import { MAccount, MAccountDefault, MAccountDefaultChannelDefault, MAccountId, MAccountIdActorId, MAccountUrl } from '../account' -import { MNotificationSetting } from './user-notification-setting' +import { PickWith, PickWithOpt } from '../../utils' +import { + MAccount, + MAccountDefault, + MAccountDefaultChannelDefault, + MAccountFormattable, + MAccountId, + MAccountIdActorId, + MAccountUrl +} from '../account' +import { MNotificationSetting, MNotificationSettingFormattable } from './user-notification-setting' +import { AccountModel } from '@server/models/account/account' +import { MChannelFormattable } from '@server/typings/models' type Use = PickWith @@ -11,6 +21,7 @@ export type MUser = Omit // ############################################################################ @@ -49,3 +60,11 @@ export type MUserNotifSettingAccount = MUser & export type MUserDefault = MUser & Use<'NotificationSetting', MNotificationSetting> & Use<'Account', MAccountDefault> + +// ############################################################################ + +// Format for API or AP object + +export type MUserFormattable = MUserQuotaUsed & + Use<'Account', MAccountFormattable & PickWithOpt> & + PickWithOpt 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 @@ import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-update' export type MScheduleVideoUpdate = Omit + +// ############################################################################ + +// Format for API or AP object + +export type MScheduleVideoUpdateFormattable = Pick 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 @@ import { VideoAbuseModel } from '../../../models/video/video-abuse' import { PickWith } from '../../utils' import { MVideo } from './video' -import { MAccountDefault } from '../account' +import { MAccountDefault, MAccountFormattable } from '../account' type Use = PickWith @@ -21,3 +21,11 @@ export type MVideoAbuseAccountVideo = MVideoAbuse & Pick & Use<'Video', MVideo> & Use<'Account', MAccountDefault> + +// ############################################################################ + +// Format for API or AP object + +export type MVideoAbuseFormattable = MVideoAbuse & + Use<'Account', MAccountFormattable> & + Use<'Video', Pick> 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 @@ import { VideoBlacklistModel } from '../../../models/video/video-blacklist' import { PickWith } from '@server/typings/utils' -import { MVideo } from '@server/typings/models' +import { MVideo, MVideoFormattable } from '@server/typings/models' type Use = PickWith @@ -15,3 +15,10 @@ export type MVideoBlacklistUnfederated = Pick export type MVideoBlacklistVideo = MVideoBlacklist & Use<'Video', MVideo> + +// ############################################################################ + +// Format for API or AP object + +export type MVideoBlacklistFormattable = MVideoBlacklist & + 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 @@ import { VideoCaptionModel } from '../../../models/video/video-caption' -import { PickWith } from '@server/typings/utils' -import { VideoModel } from '@server/models/video/video' +import { FunctionProperties, PickWith } from '@server/typings/utils' +import { MVideo, MVideoUUID } from '@server/typings/models' type Use = PickWith @@ -13,4 +13,12 @@ export type MVideoCaption = Omit export type MVideoCaptionLanguage = Pick export type MVideoCaptionVideo = MVideoCaption & - Use<'Video', Pick> + Use<'Video', Pick> + +// ############################################################################ + +// Format for API or AP object + +export type MVideoCaptionFormattable = FunctionProperties & + Pick & + 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 @@ import { VideoChangeOwnershipModel } from '@server/models/video/video-change-ownership' import { PickWith } from '@server/typings/utils' -import { MAccountDefault, MVideoWithFileThumbnail } from '@server/typings/models' +import { MAccountDefault, MAccountFormattable, MVideo, MVideoWithFileThumbnail } from '@server/typings/models' type Use = PickWith @@ -12,3 +12,12 @@ export type MVideoChangeOwnershipFull = MVideoChangeOwnership & Use<'Initiator', MAccountDefault> & Use<'NextOwner', MAccountDefault> & Use<'Video', MVideoWithFileThumbnail> + +// ############################################################################ + +// Format for API or AP object + +export type MVideoChangeOwnershipFormattable = Pick & + Use<'Initiator', MAccountFormattable> & + Use<'NextOwner', MAccountFormattable> & + Use<'Video', Pick> 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 @@ -import { PickWith } from '../../utils' +import { FunctionProperties, PickWith, PickWithOpt } from '../../utils' import { VideoChannelModel } from '../../../models/video/video-channel' import { MAccountActor, MAccountAPI, MAccountDefault, + MAccountFormattable, MAccountLight, MAccountSummaryBlocks, + MAccountSummaryFormattable, MAccountUserId, MActor, MActorAccountChannelId, MActorAPI, MActorDefault, MActorDefaultLight, + MActorFormattable, MActorLight, - MActorSummary + MActorSummary, + MActorSummaryFormattable } from '../account' import { MVideo } from './video' @@ -86,7 +90,8 @@ export type MChannelActorAccountDefaultVideos = MChannel & // For API -export type MChannelSummary = Pick & +export type MChannelSummary = FunctionProperties & + Pick & Use<'Actor', MActorSummary> export type MChannelSummaryAccount = MChannelSummary & @@ -95,3 +100,19 @@ export type MChannelSummaryAccount = MChannelSummary & export type MChannelAPI = MChannel & Use<'Actor', MActorAPI> & Use<'Account', MAccountAPI> + +// ############################################################################ + +// Format for API or AP object + +export type MChannelSummaryFormattable = FunctionProperties & + Pick & + Use<'Actor', MActorSummaryFormattable> + +export type MChannelAccountSummaryFormattable = MChannelSummaryFormattable & + Use<'Account', MAccountSummaryFormattable> + +export type MChannelFormattable = FunctionProperties & + Pick & + Use<'Actor', MActorFormattable> & + PickWithOpt 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 @@ import { VideoCommentModel } from '../../../models/video/video-comment' import { PickWith } from '../../utils' -import { MAccountDefault } from '../account' +import { MAccountDefault, MAccountFormattable } from '../account' import { MVideoAccountLight, MVideoFeed, MVideoIdUrl } from './video' type Use = PickWith @@ -8,6 +8,7 @@ type Use = PickWith +export type MCommentTotalReplies = MComment & { totalReplies?: number } export type MCommentId = Pick // ############################################################################ @@ -41,3 +42,10 @@ export type MCommentOwnerVideoFeed = MCommentOwner & // ############################################################################ export type MCommentAPI = MComment & { totalReplies: number } + +// ############################################################################ + +// Format for API or AP object + +export type MCommentFormattable = MCommentTotalReplies & + 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 @@ import { VideoImportModel } from '@server/models/video/video-import' -import { PickWith } from '@server/typings/utils' -import { MUser, MVideo, MVideoAccountLight, MVideoTag, MVideoThumbnail, MVideoWithFile } from '@server/typings/models' +import { PickWith, PickWithOpt } from '@server/typings/utils' +import { MUser, MVideo, MVideoAccountLight, MVideoFormattable, MVideoTag, MVideoThumbnail, MVideoWithFile } from '@server/typings/models' type Use = PickWith @@ -22,3 +22,10 @@ export type MVideoImportDefault = MVideoImport & export type MVideoImportDefaultFiles = MVideoImport & Use<'User', MUser> & Use<'Video', VideoAssociation & MVideoWithFile> + +// ############################################################################ + +// Format for API or AP object + +export type MVideoImportFormattable = MVideoImport & + PickWithOpt 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 @@ import { VideoPlaylistElementModel } from '@server/models/video/video-playlist-element' import { PickWith } from '@server/typings/utils' -import { MVideoPlaylistPrivacy, MVideoThumbnail, MVideoUrl } from '@server/typings/models' +import { MVideoFormattable, MVideoPlaylistPrivacy, MVideoThumbnail, MVideoUrl } from '@server/typings/models' type Use = PickWith @@ -23,6 +23,13 @@ export type MVideoPlaylistVideoThumbnail = MVideoPlaylistElement & // For API -export type MVideoPlaylistAP = MVideoPlaylistElement & +export type MVideoPlaylistElementAP = MVideoPlaylistElement & Use<'Video', MVideoUrl> & Use<'VideoPlaylist', MVideoPlaylistPrivacy> + +// ############################################################################ + +// Format for API or AP object + +export type MVideoPlaylistElementFormattable = MVideoPlaylistElement & + 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 @@ import { VideoPlaylistModel } from '../../../models/video/video-playlist' import { PickWith } from '../../utils' -import { MAccount, MAccountDefault, MAccountSummary } from '../account' +import { MAccount, MAccountDefault, MAccountSummary, MAccountSummaryFormattable } from '../account' import { MThumbnail } from './thumbnail' -import { MChannelDefault, MChannelSummary } from './video-channels' +import { MChannelDefault, MChannelSummary, MChannelSummaryFormattable } from './video-channels' import { MVideoPlaylistElementLight } from '@server/typings/models/video/video-playlist-element' type Use = PickWith @@ -16,7 +16,7 @@ export type MVideoPlaylist = Omit export type MVideoPlaylistPrivacy = Pick export type MVideoPlaylistUUID = Pick -export type MVideoPlaylistVideosLength = MVideoPlaylist & { videosLength: number } +export type MVideoPlaylistVideosLength = MVideoPlaylist & { videosLength?: number } // ############################################################################ @@ -78,3 +78,11 @@ export type MVideoPlaylistFullSummary = MVideoPlaylist & Use<'Thumbnail', MThumbnail> & Use<'OwnerAccount', MAccountSummary> & Use<'VideoChannel', MChannelSummary> + +// ############################################################################ + +// Format for API or AP object + +export type MVideoPlaylistFormattable = MVideoPlaylistVideosLength & + Use<'OwnerAccount', MAccountSummaryFormattable> & + 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 @@ import { AccountVideoRateModel } from '@server/models/account/account-video-rate' import { PickWith } from '@server/typings/utils' -import { MAccountAudience, MAccountUrl, MVideo } from '..' +import { MAccountAudience, MAccountUrl, MVideo, MVideoFormattable } from '..' type Use = PickWith @@ -14,3 +14,10 @@ export type MAccountVideoRateAccountUrl = MAccountVideoRate & export type MAccountVideoRateAccountVideo = MAccountVideoRate & Use<'Account', MAccountAudience> & Use<'Video', MVideo> + +// ############################################################################ + +// Format for API or AP object + +export type MAccountVideoRateFormattable = Pick & + 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 @@ import { VideoModel } from '../../../models/video/video' import { PickWith, PickWithOpt } from '../../utils' -import { MChannelAccountDefault, MChannelAccountLight, MChannelActor, MChannelUserId } from './video-channels' +import { + MChannelAccountDefault, + MChannelAccountLight, + MChannelAccountSummaryFormattable, + MChannelActor, + MChannelFormattable, + MChannelUserId +} from './video-channels' import { MTag } from './tag' import { MVideoCaptionLanguage } from './video-caption' import { MStreamingPlaylist, MStreamingPlaylistRedundancies } from './video-streaming-playlist' import { MVideoFile, MVideoFileRedundanciesOpt } from './video-file' import { MThumbnail } from './thumbnail' -import { MVideoBlacklistLight, MVideoBlacklistUnfederated } from './video-blacklist' +import { MVideoBlacklist, MVideoBlacklistLight, MVideoBlacklistUnfederated } from './video-blacklist' import { MScheduleVideoUpdate } from './schedule-video-update' import { MUserVideoHistoryTime } from '../user/user-video-history' @@ -144,3 +151,19 @@ export type MVideoForUser = MVideo & Use<'ScheduleVideoUpdate', MScheduleVideoUpdate> & Use<'VideoBlacklist', MVideoBlacklistLight> & Use<'Thumbnails', MThumbnail[]> + +// ############################################################################ + +// Format for API or AP object + +export type MVideoFormattable = MVideo & + PickWithOpt & + Use<'VideoChannel', MChannelAccountSummaryFormattable> & + PickWithOpt> & + PickWithOpt> + +export type MVideoFormattableDetails = MVideoFormattable & + Use<'VideoChannel', MChannelFormattable> & + Use<'Tags', MTag[]> & + Use<'VideoStreamingPlaylists', MStreamingPlaylistRedundancies[]> & + 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 = { export type FunctionProperties = Pick> -export type ValueOf = T[KT] - export type PickWith = { [P in KT]: T[P] extends V ? V : never }