Stricter models typing
This commit is contained in:
parent
9a320a06b6
commit
16c016e8b1
|
@ -3,7 +3,6 @@ import * as express from 'express'
|
||||||
function activityPubResponse (data: any, res: express.Response) {
|
function activityPubResponse (data: any, res: express.Response) {
|
||||||
return res.type('application/activity+json; charset=utf-8')
|
return res.type('application/activity+json; charset=utf-8')
|
||||||
.json(data)
|
.json(data)
|
||||||
.end()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -323,14 +323,20 @@ async function updateUser (req: express.Request, res: express.Response) {
|
||||||
const oldUserAuditView = new UserAuditView(userToUpdate.toFormattedJSON())
|
const oldUserAuditView = new UserAuditView(userToUpdate.toFormattedJSON())
|
||||||
const roleChanged = body.role !== undefined && body.role !== userToUpdate.role
|
const roleChanged = body.role !== undefined && body.role !== userToUpdate.role
|
||||||
|
|
||||||
if (body.password !== undefined) userToUpdate.password = body.password
|
const keysToUpdate: (keyof UserUpdate)[] = [
|
||||||
if (body.email !== undefined) userToUpdate.email = body.email
|
'password',
|
||||||
if (body.emailVerified !== undefined) userToUpdate.emailVerified = body.emailVerified
|
'email',
|
||||||
if (body.videoQuota !== undefined) userToUpdate.videoQuota = body.videoQuota
|
'emailVerified',
|
||||||
if (body.videoQuotaDaily !== undefined) userToUpdate.videoQuotaDaily = body.videoQuotaDaily
|
'videoQuota',
|
||||||
if (body.role !== undefined) userToUpdate.role = body.role
|
'videoQuotaDaily',
|
||||||
if (body.adminFlags !== undefined) userToUpdate.adminFlags = body.adminFlags
|
'role',
|
||||||
if (body.pluginAuth !== undefined) userToUpdate.pluginAuth = body.pluginAuth
|
'adminFlags',
|
||||||
|
'pluginAuth'
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const key of keysToUpdate) {
|
||||||
|
if (body[key] !== undefined) userToUpdate.set(key, body[key])
|
||||||
|
}
|
||||||
|
|
||||||
const user = await userToUpdate.save()
|
const user = await userToUpdate.save()
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import * as parseTorrent from 'parse-torrent'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { getEnabledResolutions } from '@server/lib/config'
|
import { getEnabledResolutions } from '@server/lib/config'
|
||||||
import { setVideoTags } from '@server/lib/video'
|
import { setVideoTags } from '@server/lib/video'
|
||||||
|
import { FilteredModelAttributes } from '@server/types'
|
||||||
import {
|
import {
|
||||||
MChannelAccountDefault,
|
MChannelAccountDefault,
|
||||||
MThumbnail,
|
MThumbnail,
|
||||||
|
@ -15,7 +16,7 @@ import {
|
||||||
MVideoThumbnail,
|
MVideoThumbnail,
|
||||||
MVideoWithBlacklistLight
|
MVideoWithBlacklistLight
|
||||||
} from '@server/types/models'
|
} from '@server/types/models'
|
||||||
import { MVideoImport, MVideoImportFormattable } from '@server/types/models/video/video-import'
|
import { MVideoImportFormattable } from '@server/types/models/video/video-import'
|
||||||
import { ServerErrorCode, VideoImportCreate, VideoImportState, VideoPrivacy, VideoState } from '../../../../shared'
|
import { ServerErrorCode, VideoImportCreate, VideoImportState, VideoPrivacy, VideoState } from '../../../../shared'
|
||||||
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
|
||||||
import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type'
|
import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type'
|
||||||
|
@ -253,7 +254,9 @@ function buildVideo (channelId: number, body: VideoImportCreate, importData: You
|
||||||
privacy: body.privacy || VideoPrivacy.PRIVATE,
|
privacy: body.privacy || VideoPrivacy.PRIVATE,
|
||||||
duration: 0, // duration will be set by the import job
|
duration: 0, // duration will be set by the import job
|
||||||
channelId: channelId,
|
channelId: channelId,
|
||||||
originallyPublishedAt: body.originallyPublishedAt || importData.originallyPublishedAt
|
originallyPublishedAt: body.originallyPublishedAt
|
||||||
|
? new Date(body.originallyPublishedAt)
|
||||||
|
: importData.originallyPublishedAt
|
||||||
}
|
}
|
||||||
const video = new VideoModel(videoData)
|
const video = new VideoModel(videoData)
|
||||||
video.url = getLocalVideoActivityPubUrl(video)
|
video.url = getLocalVideoActivityPubUrl(video)
|
||||||
|
@ -317,7 +320,7 @@ async function insertIntoDB (parameters: {
|
||||||
previewModel: MThumbnail
|
previewModel: MThumbnail
|
||||||
videoChannel: MChannelAccountDefault
|
videoChannel: MChannelAccountDefault
|
||||||
tags: string[]
|
tags: string[]
|
||||||
videoImportAttributes: Partial<MVideoImport>
|
videoImportAttributes: FilteredModelAttributes<VideoImportModel>
|
||||||
user: MUser
|
user: MUser
|
||||||
}): Promise<MVideoImportFormattable> {
|
}): Promise<MVideoImportFormattable> {
|
||||||
const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters
|
const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters
|
||||||
|
|
|
@ -308,7 +308,7 @@ async function addVideo (options: {
|
||||||
if (videoInfo.scheduleUpdate) {
|
if (videoInfo.scheduleUpdate) {
|
||||||
await ScheduleVideoUpdateModel.create({
|
await ScheduleVideoUpdateModel.create({
|
||||||
videoId: video.id,
|
videoId: video.id,
|
||||||
updateAt: videoInfo.scheduleUpdate.updateAt,
|
updateAt: new Date(videoInfo.scheduleUpdate.updateAt),
|
||||||
privacy: videoInfo.scheduleUpdate.privacy || null
|
privacy: videoInfo.scheduleUpdate.privacy || null
|
||||||
}, { transaction: t })
|
}, { transaction: t })
|
||||||
}
|
}
|
||||||
|
@ -435,7 +435,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
|
||||||
if (videoInfoToUpdate.scheduleUpdate) {
|
if (videoInfoToUpdate.scheduleUpdate) {
|
||||||
await ScheduleVideoUpdateModel.upsert({
|
await ScheduleVideoUpdateModel.upsert({
|
||||||
videoId: videoInstanceUpdated.id,
|
videoId: videoInstanceUpdated.id,
|
||||||
updateAt: videoInfoToUpdate.scheduleUpdate.updateAt,
|
updateAt: new Date(videoInfoToUpdate.scheduleUpdate.updateAt),
|
||||||
privacy: videoInfoToUpdate.scheduleUpdate.privacy || null
|
privacy: videoInfoToUpdate.scheduleUpdate.privacy || null
|
||||||
}, { transaction: t })
|
}, { transaction: t })
|
||||||
} else if (videoInfoToUpdate.scheduleUpdate === null) {
|
} else if (videoInfoToUpdate.scheduleUpdate === null) {
|
||||||
|
|
|
@ -68,7 +68,7 @@ function transactionRetryer <T> (func: (err: any, data: T) => any) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateInstanceWithAnother <T extends Model<T>> (instanceToUpdate: Model<T>, baseInstance: Model<T>) {
|
function updateInstanceWithAnother <M, T extends U, U extends Model<M>> (instanceToUpdate: T, baseInstance: U) {
|
||||||
const obj = baseInstance.toJSON()
|
const obj = baseInstance.toJSON()
|
||||||
|
|
||||||
for (const key of Object.keys(obj)) {
|
for (const key of Object.keys(obj)) {
|
||||||
|
@ -88,7 +88,7 @@ function afterCommitIfTransaction (t: Transaction, fn: Function) {
|
||||||
return fn()
|
return fn()
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteNonExistingModels <T extends { hasSameUniqueKeysThan (other: T): boolean } & Model<T>> (
|
function deleteNonExistingModels <T extends { hasSameUniqueKeysThan (other: T): boolean } & Pick<Model, 'destroy'>> (
|
||||||
fromDatabase: T[],
|
fromDatabase: T[],
|
||||||
newModels: T[],
|
newModels: T[],
|
||||||
t: Transaction
|
t: Transaction
|
||||||
|
|
|
@ -132,12 +132,11 @@ async function getOrCreateActorAndServerAndModel (
|
||||||
return actorRefreshed
|
return actorRefreshed
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildActorInstance (type: ActivityPubActorType, url: string, preferredUsername: string, uuid?: string) {
|
function buildActorInstance (type: ActivityPubActorType, url: string, preferredUsername: string) {
|
||||||
return new ActorModel({
|
return new ActorModel({
|
||||||
type,
|
type,
|
||||||
url,
|
url,
|
||||||
preferredUsername,
|
preferredUsername,
|
||||||
uuid,
|
|
||||||
publicKey: null,
|
publicKey: null,
|
||||||
privateKey: null,
|
privateKey: null,
|
||||||
followersCount: 0,
|
followersCount: 0,
|
||||||
|
|
|
@ -36,8 +36,8 @@ async function processVideosViews () {
|
||||||
}
|
}
|
||||||
|
|
||||||
await VideoViewModel.create({
|
await VideoViewModel.create({
|
||||||
startDate,
|
startDate: new Date(startDate),
|
||||||
endDate,
|
endDate: new Date(endDate),
|
||||||
views,
|
views,
|
||||||
videoId
|
videoId
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
|
||||||
import { VideoChannelCreate } from '../../shared/models'
|
import { VideoChannelCreate } from '../../shared/models'
|
||||||
import { VideoModel } from '../models/video/video'
|
import { VideoModel } from '../models/video/video'
|
||||||
import { VideoChannelModel } from '../models/video/video-channel'
|
import { VideoChannelModel } from '../models/video/video-channel'
|
||||||
|
@ -9,9 +8,8 @@ import { getLocalVideoChannelActivityPubUrl } from './activitypub/url'
|
||||||
import { federateVideoIfNeeded } from './activitypub/videos'
|
import { federateVideoIfNeeded } from './activitypub/videos'
|
||||||
|
|
||||||
async function createLocalVideoChannel (videoChannelInfo: VideoChannelCreate, account: MAccountId, t: Sequelize.Transaction) {
|
async function createLocalVideoChannel (videoChannelInfo: VideoChannelCreate, account: MAccountId, t: Sequelize.Transaction) {
|
||||||
const uuid = uuidv4()
|
|
||||||
const url = getLocalVideoChannelActivityPubUrl(videoChannelInfo.name)
|
const url = getLocalVideoChannelActivityPubUrl(videoChannelInfo.name)
|
||||||
const actorInstance = buildActorInstance('Group', url, videoChannelInfo.name, uuid)
|
const actorInstance = buildActorInstance('Group', url, videoChannelInfo.name)
|
||||||
|
|
||||||
const actorInstanceCreated = await actorInstance.save({ transaction: t })
|
const actorInstanceCreated = await actorInstance.save({ transaction: t })
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@ function buildLocalVideoFromReq (videoInfo: VideoCreate, channelId: number): Fil
|
||||||
privacy: videoInfo.privacy || VideoPrivacy.PRIVATE,
|
privacy: videoInfo.privacy || VideoPrivacy.PRIVATE,
|
||||||
channelId: channelId,
|
channelId: channelId,
|
||||||
originallyPublishedAt: videoInfo.originallyPublishedAt
|
originallyPublishedAt: videoInfo.originallyPublishedAt
|
||||||
|
? new Date(videoInfo.originallyPublishedAt)
|
||||||
|
: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { isAbuseMessageValid } from '@server/helpers/custom-validators/abuses'
|
import { isAbuseMessageValid } from '@server/helpers/custom-validators/abuses'
|
||||||
import { MAbuseMessage, MAbuseMessageFormattable } from '@server/types/models'
|
import { MAbuseMessage, MAbuseMessageFormattable } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { AbuseMessage } from '@shared/models'
|
import { AbuseMessage } from '@shared/models'
|
||||||
import { AccountModel, ScopeNames as AccountScopeNames } from '../account/account'
|
import { AccountModel, ScopeNames as AccountScopeNames } from '../account/account'
|
||||||
import { getSort, throwIfNotValid } from '../utils'
|
import { getSort, throwIfNotValid } from '../utils'
|
||||||
|
@ -17,7 +18,7 @@ import { AbuseModel } from './abuse'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AbuseMessageModel extends Model {
|
export class AbuseMessageModel extends Model<Partial<AttributesOnly<AbuseMessageModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Is('AbuseMessage', value => throwIfNotValid(value, isAbuseMessageValid, 'message'))
|
@Is('AbuseMessage', value => throwIfNotValid(value, isAbuseMessageValid, 'message'))
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {
|
||||||
UpdatedAt
|
UpdatedAt
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { isAbuseModerationCommentValid, isAbuseReasonValid, isAbuseStateValid } from '@server/helpers/custom-validators/abuses'
|
import { isAbuseModerationCommentValid, isAbuseReasonValid, isAbuseStateValid } from '@server/helpers/custom-validators/abuses'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { abusePredefinedReasonsMap } from '@shared/core-utils/abuse'
|
import { abusePredefinedReasonsMap } from '@shared/core-utils/abuse'
|
||||||
import {
|
import {
|
||||||
AbuseFilter,
|
AbuseFilter,
|
||||||
|
@ -187,7 +188,7 @@ export enum ScopeNames {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AbuseModel extends Model {
|
export class AbuseModel extends Model<Partial<AttributesOnly<AbuseModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Default(null)
|
@Default(null)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoDetails } from '@shared/models'
|
import { VideoDetails } from '@shared/models'
|
||||||
import { VideoModel } from '../video/video'
|
import { VideoModel } from '../video/video'
|
||||||
import { AbuseModel } from './abuse'
|
import { AbuseModel } from './abuse'
|
||||||
|
@ -14,7 +15,7 @@ import { AbuseModel } from './abuse'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoAbuseModel extends Model {
|
export class VideoAbuseModel extends Model<Partial<AttributesOnly<VideoAbuseModel>>> {
|
||||||
|
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoCommentModel } from '../video/video-comment'
|
import { VideoCommentModel } from '../video/video-comment'
|
||||||
import { AbuseModel } from './abuse'
|
import { AbuseModel } from './abuse'
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ import { AbuseModel } from './abuse'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoCommentAbuseModel extends Model {
|
export class VideoCommentAbuseModel extends Model<Partial<AttributesOnly<VideoCommentAbuseModel>>> {
|
||||||
|
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Op } from 'sequelize'
|
import { Op } from 'sequelize'
|
||||||
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { MAccountBlocklist, MAccountBlocklistAccounts, MAccountBlocklistFormattable } from '@server/types/models'
|
import { MAccountBlocklist, MAccountBlocklistAccounts, MAccountBlocklistFormattable } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { AccountBlock } from '../../../shared/models'
|
import { AccountBlock } from '../../../shared/models'
|
||||||
import { ActorModel } from '../actor/actor'
|
import { ActorModel } from '../actor/actor'
|
||||||
import { ServerModel } from '../server/server'
|
import { ServerModel } from '../server/server'
|
||||||
|
@ -40,7 +41,7 @@ enum ScopeNames {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AccountBlocklistModel extends Model {
|
export class AccountBlocklistModel extends Model<Partial<AttributesOnly<AccountBlocklistModel>>> {
|
||||||
|
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
MAccountVideoRateAccountVideo,
|
MAccountVideoRateAccountVideo,
|
||||||
MAccountVideoRateFormattable
|
MAccountVideoRateFormattable
|
||||||
} from '@server/types/models/video/video-rate'
|
} from '@server/types/models/video/video-rate'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { AccountVideoRate } from '../../../shared'
|
import { AccountVideoRate } from '../../../shared'
|
||||||
import { VideoRateType } from '../../../shared/models/videos'
|
import { VideoRateType } from '../../../shared/models/videos'
|
||||||
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
||||||
|
@ -42,7 +43,7 @@ import { AccountModel } from './account'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AccountVideoRateModel extends Model {
|
export class AccountVideoRateModel extends Model<Partial<AttributesOnly<AccountVideoRateModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Column(DataType.ENUM(...values(VIDEO_RATE_TYPES)))
|
@Column(DataType.ENUM(...values(VIDEO_RATE_TYPES)))
|
||||||
|
|
|
@ -17,6 +17,7 @@ import {
|
||||||
UpdatedAt
|
UpdatedAt
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { ModelCache } from '@server/models/model-cache'
|
import { ModelCache } from '@server/models/model-cache'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { Account, AccountSummary } from '../../../shared/models/actors'
|
import { Account, AccountSummary } from '../../../shared/models/actors'
|
||||||
import { isAccountDescriptionValid } from '../../helpers/custom-validators/accounts'
|
import { isAccountDescriptionValid } from '../../helpers/custom-validators/accounts'
|
||||||
import { CONSTRAINTS_FIELDS, SERVER_ACTOR_NAME, WEBSERVER } from '../../initializers/constants'
|
import { CONSTRAINTS_FIELDS, SERVER_ACTOR_NAME, WEBSERVER } from '../../initializers/constants'
|
||||||
|
@ -141,7 +142,7 @@ export type SummaryOptions = {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AccountModel extends Model {
|
export class AccountModel extends Model<Partial<AttributesOnly<AccountModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Column
|
@Column
|
||||||
|
|
|
@ -28,6 +28,7 @@ import {
|
||||||
MActorFollowFormattable,
|
MActorFollowFormattable,
|
||||||
MActorFollowSubscriptions
|
MActorFollowSubscriptions
|
||||||
} from '@server/types/models'
|
} from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { ActivityPubActorType } from '@shared/models'
|
import { ActivityPubActorType } from '@shared/models'
|
||||||
import { FollowState } from '../../../shared/models/actors'
|
import { FollowState } from '../../../shared/models/actors'
|
||||||
import { ActorFollow } from '../../../shared/models/actors/follow.model'
|
import { ActorFollow } from '../../../shared/models/actors/follow.model'
|
||||||
|
@ -61,7 +62,7 @@ import { ActorModel, unusedActorAttributesForAPI } from './actor'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ActorFollowModel extends Model {
|
export class ActorFollowModel extends Model<Partial<AttributesOnly<ActorFollowModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Column(DataType.ENUM(...values(FOLLOW_STATES)))
|
@Column(DataType.ENUM(...values(FOLLOW_STATES)))
|
||||||
|
@ -619,7 +620,7 @@ export class ActorFollowModel extends Model {
|
||||||
if (serverIds.length === 0) return
|
if (serverIds.length === 0) return
|
||||||
|
|
||||||
const me = await getServerActor()
|
const me = await getServerActor()
|
||||||
const serverIdsString = createSafeIn(ActorFollowModel, serverIds)
|
const serverIdsString = createSafeIn(ActorFollowModel.sequelize, serverIds)
|
||||||
|
|
||||||
const query = `UPDATE "actorFollow" SET "score" = LEAST("score" + ${value}, ${ACTOR_FOLLOW_SCORE.MAX}) ` +
|
const query = `UPDATE "actorFollow" SET "score" = LEAST("score" + ${value}, ${ACTOR_FOLLOW_SCORE.MAX}) ` +
|
||||||
'WHERE id IN (' +
|
'WHERE id IN (' +
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { remove } from 'fs-extra'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { AfterDestroy, AllowNull, Column, CreatedAt, Default, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AfterDestroy, AllowNull, Column, CreatedAt, Default, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { MActorImageFormattable } from '@server/types/models'
|
import { MActorImageFormattable } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { ActorImageType } from '@shared/models'
|
import { ActorImageType } from '@shared/models'
|
||||||
import { ActorImage } from '../../../shared/models/actors/actor-image.model'
|
import { ActorImage } from '../../../shared/models/actors/actor-image.model'
|
||||||
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
||||||
|
@ -19,7 +20,7 @@ import { throwIfNotValid } from '../utils'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ActorImageModel extends Model {
|
export class ActorImageModel extends Model<Partial<AttributesOnly<ActorImageModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Column
|
@Column
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {
|
||||||
UpdatedAt
|
UpdatedAt
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { ModelCache } from '@server/models/model-cache'
|
import { ModelCache } from '@server/models/model-cache'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { ActivityIconObject, ActivityPubActorType } from '../../../shared/models/activitypub'
|
import { ActivityIconObject, ActivityPubActorType } from '../../../shared/models/activitypub'
|
||||||
import { ActorImage } from '../../../shared/models/actors/actor-image.model'
|
import { ActorImage } from '../../../shared/models/actors/actor-image.model'
|
||||||
import { activityPubContextify } from '../../helpers/activitypub'
|
import { activityPubContextify } from '../../helpers/activitypub'
|
||||||
|
@ -159,7 +160,7 @@ export const unusedActorAttributesForAPI = [
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ActorModel extends Model {
|
export class ActorModel extends Model<Partial<AttributesOnly<ActorModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Column(DataType.ENUM(...values(ACTIVITY_PUB_ACTOR_TYPES)))
|
@Column(DataType.ENUM(...values(ACTIVITY_PUB_ACTOR_TYPES)))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { AllowNull, Column, Default, DefaultScope, HasOne, IsInt, Model, Table } from 'sequelize-typescript'
|
|
||||||
import { AccountModel } from '../account/account'
|
|
||||||
import * as memoizee from 'memoizee'
|
import * as memoizee from 'memoizee'
|
||||||
|
import { AllowNull, Column, Default, DefaultScope, HasOne, IsInt, Model, Table } from 'sequelize-typescript'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
|
import { AccountModel } from '../account/account'
|
||||||
|
|
||||||
export const getServerActor = memoizee(async function () {
|
export const getServerActor = memoizee(async function () {
|
||||||
const application = await ApplicationModel.load()
|
const application = await ApplicationModel.load()
|
||||||
|
@ -24,7 +25,7 @@ export const getServerActor = memoizee(async function () {
|
||||||
tableName: 'application',
|
tableName: 'application',
|
||||||
timestamps: false
|
timestamps: false
|
||||||
})
|
})
|
||||||
export class ApplicationModel extends Model {
|
export class ApplicationModel extends Model<Partial<AttributesOnly<ApplicationModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Default(0)
|
@Default(0)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { AllowNull, Column, CreatedAt, DataType, HasMany, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, Column, CreatedAt, DataType, HasMany, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { OAuthTokenModel } from './oauth-token'
|
import { OAuthTokenModel } from './oauth-token'
|
||||||
|
|
||||||
@Table({
|
@Table({
|
||||||
|
@ -14,7 +15,7 @@ import { OAuthTokenModel } from './oauth-token'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class OAuthClientModel extends Model {
|
export class OAuthClientModel extends Model<Partial<AttributesOnly<OAuthClientModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Column
|
@Column
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
import { TokensCache } from '@server/lib/auth/tokens-cache'
|
import { TokensCache } from '@server/lib/auth/tokens-cache'
|
||||||
import { MUserAccountId } from '@server/types/models'
|
import { MUserAccountId } from '@server/types/models'
|
||||||
import { MOAuthTokenUser } from '@server/types/models/oauth/oauth-token'
|
import { MOAuthTokenUser } from '@server/types/models/oauth/oauth-token'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { logger } from '../../helpers/logger'
|
import { logger } from '../../helpers/logger'
|
||||||
import { AccountModel } from '../account/account'
|
import { AccountModel } from '../account/account'
|
||||||
import { ActorModel } from '../actor/actor'
|
import { ActorModel } from '../actor/actor'
|
||||||
|
@ -78,7 +79,7 @@ enum ScopeNames {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class OAuthTokenModel extends Model {
|
export class OAuthTokenModel extends Model<Partial<AttributesOnly<OAuthTokenModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Column
|
@Column
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { getServerActor } from '@server/models/application/application'
|
import { getServerActor } from '@server/models/application/application'
|
||||||
import { MActor, MVideoForRedundancyAPI, MVideoRedundancy, MVideoRedundancyAP, MVideoRedundancyVideo } from '@server/types/models'
|
import { MActor, MVideoForRedundancyAPI, MVideoRedundancy, MVideoRedundancyAP, MVideoRedundancyVideo } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoRedundanciesTarget } from '@shared/models/redundancy/video-redundancies-filters.model'
|
import { VideoRedundanciesTarget } from '@shared/models/redundancy/video-redundancies-filters.model'
|
||||||
import {
|
import {
|
||||||
FileRedundancyInformation,
|
FileRedundancyInformation,
|
||||||
|
@ -84,7 +85,7 @@ export enum ScopeNames {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoRedundancyModel extends Model {
|
export class VideoRedundancyModel extends Model<Partial<AttributesOnly<VideoRedundancyModel>>> {
|
||||||
|
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { FindAndCountOptions, json, QueryTypes } from 'sequelize'
|
import { FindAndCountOptions, json, QueryTypes } from 'sequelize'
|
||||||
import { AllowNull, Column, CreatedAt, DataType, DefaultScope, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, Column, CreatedAt, DataType, DefaultScope, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { MPlugin, MPluginFormattable } from '@server/types/models'
|
import { MPlugin, MPluginFormattable } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { PeerTubePlugin, PluginType, RegisterServerSettingOptions } from '../../../shared/models'
|
import { PeerTubePlugin, PluginType, RegisterServerSettingOptions } from '../../../shared/models'
|
||||||
import {
|
import {
|
||||||
isPluginDescriptionValid,
|
isPluginDescriptionValid,
|
||||||
|
@ -26,7 +27,7 @@ import { getSort, throwIfNotValid } from '../utils'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class PluginModel extends Model {
|
export class PluginModel extends Model<Partial<AttributesOnly<PluginModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Is('PluginName', value => throwIfNotValid(value, isPluginNameValid, 'name'))
|
@Is('PluginName', value => throwIfNotValid(value, isPluginNameValid, 'name'))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Op } from 'sequelize'
|
import { Op } from 'sequelize'
|
||||||
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/types/models'
|
import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { ServerBlock } from '@shared/models'
|
import { ServerBlock } from '@shared/models'
|
||||||
import { AccountModel } from '../account/account'
|
import { AccountModel } from '../account/account'
|
||||||
import { getSort, searchAttribute } from '../utils'
|
import { getSort, searchAttribute } from '../utils'
|
||||||
|
@ -42,7 +43,7 @@ enum ScopeNames {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ServerBlocklistModel extends Model {
|
export class ServerBlocklistModel extends Model<Partial<AttributesOnly<ServerBlocklistModel>>> {
|
||||||
|
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { AllowNull, Column, CreatedAt, Default, HasMany, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, Column, CreatedAt, Default, HasMany, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { MServer, MServerFormattable } from '@server/types/models/server'
|
import { MServer, MServerFormattable } from '@server/types/models/server'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { isHostValid } from '../../helpers/custom-validators/servers'
|
import { isHostValid } from '../../helpers/custom-validators/servers'
|
||||||
import { ActorModel } from '../actor/actor'
|
import { ActorModel } from '../actor/actor'
|
||||||
import { throwIfNotValid } from '../utils'
|
import { throwIfNotValid } from '../utils'
|
||||||
|
@ -14,7 +15,7 @@ import { ServerBlocklistModel } from './server-blocklist'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ServerModel extends Model {
|
export class ServerModel extends Model<Partial<AttributesOnly<ServerModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Is('Host', value => throwIfNotValid(value, isHostValid, 'valid host'))
|
@Is('Host', value => throwIfNotValid(value, isHostValid, 'valid host'))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { AllowNull, BelongsToMany, Column, CreatedAt, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, BelongsToMany, Column, CreatedAt, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { Transaction } from 'sequelize/types'
|
import { Transaction } from 'sequelize/types'
|
||||||
import { MTracker } from '@server/types/models/server/tracker'
|
import { MTracker } from '@server/types/models/server/tracker'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoModel } from '../video/video'
|
import { VideoModel } from '../video/video'
|
||||||
import { VideoTrackerModel } from './video-tracker'
|
import { VideoTrackerModel } from './video-tracker'
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ import { VideoTrackerModel } from './video-tracker'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class TrackerModel extends Model {
|
export class TrackerModel extends Model<Partial<AttributesOnly<TrackerModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Column
|
@Column
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoModel } from '../video/video'
|
import { VideoModel } from '../video/video'
|
||||||
import { TrackerModel } from './tracker'
|
import { TrackerModel } from './tracker'
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ import { TrackerModel } from './tracker'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoTrackerModel extends Model {
|
export class VideoTrackerModel extends Model<Partial<AttributesOnly<VideoTrackerModel>>> {
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { TokensCache } from '@server/lib/auth/tokens-cache'
|
import { TokensCache } from '@server/lib/auth/tokens-cache'
|
||||||
import { MNotificationSettingFormattable } from '@server/types/models'
|
import { MNotificationSettingFormattable } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { UserNotificationSetting, UserNotificationSettingValue } from '../../../shared/models/users/user-notification-setting.model'
|
import { UserNotificationSetting, UserNotificationSettingValue } from '../../../shared/models/users/user-notification-setting.model'
|
||||||
import { isUserNotificationSettingValid } from '../../helpers/custom-validators/user-notifications'
|
import { isUserNotificationSettingValid } from '../../helpers/custom-validators/user-notifications'
|
||||||
import { throwIfNotValid } from '../utils'
|
import { throwIfNotValid } from '../utils'
|
||||||
|
@ -28,7 +29,7 @@ import { UserModel } from './user'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class UserNotificationSettingModel extends Model {
|
export class UserNotificationSettingModel extends Model<Partial<AttributesOnly<UserNotificationSettingModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Default(null)
|
@Default(null)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { FindOptions, ModelIndexesOptions, Op, WhereOptions } from 'sequelize'
|
import { FindOptions, ModelIndexesOptions, Op, WhereOptions } from 'sequelize'
|
||||||
import { AllowNull, BelongsTo, Column, CreatedAt, Default, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, BelongsTo, Column, CreatedAt, Default, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { UserNotificationIncludes, UserNotificationModelForApi } from '@server/types/models/user'
|
import { UserNotificationIncludes, UserNotificationModelForApi } from '@server/types/models/user'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { UserNotification, UserNotificationType } from '../../../shared'
|
import { UserNotification, UserNotificationType } from '../../../shared'
|
||||||
import { isBooleanValid } from '../../helpers/custom-validators/misc'
|
import { isBooleanValid } from '../../helpers/custom-validators/misc'
|
||||||
import { isUserNotificationTypeValid } from '../../helpers/custom-validators/user-notifications'
|
import { isUserNotificationTypeValid } from '../../helpers/custom-validators/user-notifications'
|
||||||
|
@ -286,7 +287,7 @@ function buildAccountInclude (required: boolean, withActor = false) {
|
||||||
}
|
}
|
||||||
] as (ModelIndexesOptions & { where?: WhereOptions })[]
|
] as (ModelIndexesOptions & { where?: WhereOptions })[]
|
||||||
})
|
})
|
||||||
export class UserNotificationModel extends Model {
|
export class UserNotificationModel extends Model<Partial<AttributesOnly<UserNotificationModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Default(null)
|
@Default(null)
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
import { DestroyOptions, Op, Transaction } from 'sequelize'
|
||||||
import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, IsInt, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, IsInt, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
|
import { MUserAccountId, MUserId } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoModel } from '../video/video'
|
import { VideoModel } from '../video/video'
|
||||||
import { UserModel } from './user'
|
import { UserModel } from './user'
|
||||||
import { DestroyOptions, Op, Transaction } from 'sequelize'
|
|
||||||
import { MUserAccountId, MUserId } from '@server/types/models'
|
|
||||||
|
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'userVideoHistory',
|
tableName: 'userVideoHistory',
|
||||||
|
@ -19,7 +20,7 @@ import { MUserAccountId, MUserId } from '@server/types/models'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class UserVideoHistoryModel extends Model {
|
export class UserVideoHistoryModel extends Model<Partial<AttributesOnly<UserVideoHistoryModel>>> {
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import {
|
||||||
MUserWithNotificationSetting,
|
MUserWithNotificationSetting,
|
||||||
MVideoWithRights
|
MVideoWithRights
|
||||||
} from '@server/types/models'
|
} from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { hasUserRight, USER_ROLE_LABELS } from '../../../shared/core-utils/users'
|
import { hasUserRight, USER_ROLE_LABELS } from '../../../shared/core-utils/users'
|
||||||
import { AbuseState, MyUser, UserRight, VideoPlaylistType, VideoPrivacy } from '../../../shared/models'
|
import { AbuseState, MyUser, UserRight, VideoPlaylistType, VideoPrivacy } from '../../../shared/models'
|
||||||
import { User, UserRole } from '../../../shared/models/users'
|
import { User, UserRole } from '../../../shared/models/users'
|
||||||
|
@ -233,7 +234,7 @@ enum ScopeNames {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class UserModel extends Model {
|
export class UserModel extends Model<Partial<AttributesOnly<UserModel>>> {
|
||||||
|
|
||||||
@AllowNull(true)
|
@AllowNull(true)
|
||||||
@Is('UserPassword', value => throwIfNotValid(value, isUserPasswordValid, 'user password', true))
|
@Is('UserPassword', value => throwIfNotValid(value, isUserPasswordValid, 'user password', true))
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { literal, Op, OrderItem } from 'sequelize'
|
import { literal, Op, OrderItem, Sequelize } from 'sequelize'
|
||||||
import { Model, Sequelize } from 'sequelize-typescript'
|
|
||||||
import { Col } from 'sequelize/types/lib/utils'
|
import { Col } from 'sequelize/types/lib/utils'
|
||||||
import validator from 'validator'
|
import validator from 'validator'
|
||||||
|
|
||||||
|
@ -195,11 +194,11 @@ function parseAggregateResult (result: any) {
|
||||||
return total
|
return total
|
||||||
}
|
}
|
||||||
|
|
||||||
const createSafeIn = (model: typeof Model, stringArr: (string | number)[]) => {
|
function createSafeIn (sequelize: Sequelize, stringArr: (string | number)[]) {
|
||||||
return stringArr.map(t => {
|
return stringArr.map(t => {
|
||||||
return t === null
|
return t === null
|
||||||
? null
|
? null
|
||||||
: model.sequelize.escape('' + t)
|
: sequelize.escape('' + t)
|
||||||
}).join(', ')
|
}).join(', ')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { AllowNull, BelongsTo, Column, CreatedAt, Default, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
|
||||||
import { ScopeNames as VideoScopeNames, VideoModel } from './video'
|
|
||||||
import { VideoPrivacy } from '../../../shared/models/videos'
|
|
||||||
import { Op, Transaction } from 'sequelize'
|
import { Op, Transaction } from 'sequelize'
|
||||||
|
import { AllowNull, BelongsTo, Column, CreatedAt, Default, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { MScheduleVideoUpdateFormattable, MScheduleVideoUpdateVideoAll } from '@server/types/models'
|
import { MScheduleVideoUpdateFormattable, MScheduleVideoUpdateVideoAll } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
|
import { VideoPrivacy } from '../../../shared/models/videos'
|
||||||
|
import { ScopeNames as VideoScopeNames, VideoModel } from './video'
|
||||||
|
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'scheduleVideoUpdate',
|
tableName: 'scheduleVideoUpdate',
|
||||||
|
@ -16,7 +17,7 @@ import { MScheduleVideoUpdateFormattable, MScheduleVideoUpdateVideoAll } from '@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ScheduleVideoUpdateModel extends Model {
|
export class ScheduleVideoUpdateModel extends Model<Partial<AttributesOnly<ScheduleVideoUpdateModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Default(null)
|
@Default(null)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { col, fn, QueryTypes, Transaction } from 'sequelize'
|
import { col, fn, QueryTypes, Transaction } from 'sequelize'
|
||||||
import { AllowNull, BelongsToMany, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, BelongsToMany, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { MTag } from '@server/types/models'
|
import { MTag } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoPrivacy, VideoState } from '../../../shared/models/videos'
|
import { VideoPrivacy, VideoState } from '../../../shared/models/videos'
|
||||||
import { isVideoTagValid } from '../../helpers/custom-validators/videos'
|
import { isVideoTagValid } from '../../helpers/custom-validators/videos'
|
||||||
import { throwIfNotValid } from '../utils'
|
import { throwIfNotValid } from '../utils'
|
||||||
|
@ -21,7 +22,7 @@ import { VideoTagModel } from './video-tag'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class TagModel extends Model {
|
export class TagModel extends Model<Partial<AttributesOnly<TagModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Is('VideoTag', value => throwIfNotValid(value, isVideoTagValid, 'tag'))
|
@Is('VideoTag', value => throwIfNotValid(value, isVideoTagValid, 'tag'))
|
||||||
|
|
|
@ -17,6 +17,7 @@ import {
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { afterCommitIfTransaction } from '@server/helpers/database-utils'
|
import { afterCommitIfTransaction } from '@server/helpers/database-utils'
|
||||||
import { MThumbnail, MThumbnailVideo, MVideo } from '@server/types/models'
|
import { MThumbnail, MThumbnailVideo, MVideo } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type'
|
import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type'
|
||||||
import { logger } from '../../helpers/logger'
|
import { logger } from '../../helpers/logger'
|
||||||
import { CONFIG } from '../../initializers/config'
|
import { CONFIG } from '../../initializers/config'
|
||||||
|
@ -40,7 +41,7 @@ import { VideoPlaylistModel } from './video-playlist'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ThumbnailModel extends Model {
|
export class ThumbnailModel extends Model<Partial<AttributesOnly<ThumbnailModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Column
|
@Column
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { FindOptions } from 'sequelize'
|
import { FindOptions } from 'sequelize'
|
||||||
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { MVideoBlacklist, MVideoBlacklistFormattable } from '@server/types/models'
|
import { MVideoBlacklist, MVideoBlacklistFormattable } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoBlacklist, VideoBlacklistType } from '../../../shared/models/videos'
|
import { VideoBlacklist, VideoBlacklistType } from '../../../shared/models/videos'
|
||||||
import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist'
|
import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist'
|
||||||
import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
|
import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
|
||||||
|
@ -18,7 +19,7 @@ import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoBlacklistModel extends Model {
|
export class VideoBlacklistModel extends Model<Partial<AttributesOnly<VideoBlacklistModel>>> {
|
||||||
|
|
||||||
@AllowNull(true)
|
@AllowNull(true)
|
||||||
@Is('VideoBlacklistReason', value => throwIfNotValid(value, isVideoBlacklistReasonValid, 'reason', true))
|
@Is('VideoBlacklistReason', value => throwIfNotValid(value, isVideoBlacklistReasonValid, 'reason', true))
|
||||||
|
|
|
@ -17,6 +17,7 @@ import {
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { MVideo, MVideoCaption, MVideoCaptionFormattable, MVideoCaptionVideo } from '@server/types/models'
|
import { MVideo, MVideoCaption, MVideoCaptionFormattable, MVideoCaptionVideo } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoCaption } from '../../../shared/models/videos/caption/video-caption.model'
|
import { VideoCaption } from '../../../shared/models/videos/caption/video-caption.model'
|
||||||
import { isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions'
|
import { isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions'
|
||||||
import { logger } from '../../helpers/logger'
|
import { logger } from '../../helpers/logger'
|
||||||
|
@ -57,7 +58,7 @@ export enum ScopeNames {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoCaptionModel extends Model {
|
export class VideoCaptionModel extends Model<Partial<AttributesOnly<VideoCaptionModel>>> {
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { MVideoChangeOwnershipFormattable, MVideoChangeOwnershipFull } from '@server/types/models/video/video-change-ownership'
|
import { MVideoChangeOwnershipFormattable, MVideoChangeOwnershipFull } from '@server/types/models/video/video-change-ownership'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '../../../shared/models/videos'
|
import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '../../../shared/models/videos'
|
||||||
import { AccountModel } from '../account/account'
|
import { AccountModel } from '../account/account'
|
||||||
import { getSort } from '../utils'
|
import { getSort } from '../utils'
|
||||||
|
@ -53,7 +54,7 @@ enum ScopeNames {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
export class VideoChangeOwnershipModel extends Model {
|
export class VideoChangeOwnershipModel extends Model<Partial<AttributesOnly<VideoChangeOwnershipModel>>> {
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { setAsUpdated } from '@server/helpers/database-utils'
|
import { setAsUpdated } from '@server/helpers/database-utils'
|
||||||
import { MAccountActor } from '@server/types/models'
|
import { MAccountActor } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { ActivityPubActor } from '../../../shared/models/activitypub'
|
import { ActivityPubActor } from '../../../shared/models/activitypub'
|
||||||
import { VideoChannel, VideoChannelSummary } from '../../../shared/models/videos'
|
import { VideoChannel, VideoChannelSummary } from '../../../shared/models/videos'
|
||||||
import {
|
import {
|
||||||
|
@ -246,7 +247,7 @@ export type SummaryOptions = {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoChannelModel extends Model {
|
export class VideoChannelModel extends Model<Partial<AttributesOnly<VideoChannelModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Is('VideoChannelName', value => throwIfNotValid(value, isVideoChannelNameValid, 'name'))
|
@Is('VideoChannelName', value => throwIfNotValid(value, isVideoChannelNameValid, 'name'))
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { getServerActor } from '@server/models/application/application'
|
import { getServerActor } from '@server/models/application/application'
|
||||||
import { MAccount, MAccountId, MUserAccountId } from '@server/types/models'
|
import { MAccount, MAccountId, MUserAccountId } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoPrivacy } from '@shared/models'
|
import { VideoPrivacy } from '@shared/models'
|
||||||
import { ActivityTagObject, ActivityTombstoneObject } from '../../../shared/models/activitypub/objects/common-objects'
|
import { ActivityTagObject, ActivityTombstoneObject } from '../../../shared/models/activitypub/objects/common-objects'
|
||||||
import { VideoCommentObject } from '../../../shared/models/activitypub/objects/video-comment-object'
|
import { VideoCommentObject } from '../../../shared/models/activitypub/objects/video-comment-object'
|
||||||
|
@ -173,7 +174,7 @@ export enum ScopeNames {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoCommentModel extends Model {
|
export class VideoCommentModel extends Model<Partial<AttributesOnly<VideoCommentModel>>> {
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { logger } from '@server/helpers/logger'
|
||||||
import { extractVideo } from '@server/helpers/video'
|
import { extractVideo } from '@server/helpers/video'
|
||||||
import { getTorrentFilePath } from '@server/lib/video-paths'
|
import { getTorrentFilePath } from '@server/lib/video-paths'
|
||||||
import { MStreamingPlaylistVideo, MVideo, MVideoWithHost } from '@server/types/models'
|
import { MStreamingPlaylistVideo, MVideo, MVideoWithHost } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import {
|
import {
|
||||||
isVideoFileExtnameValid,
|
isVideoFileExtnameValid,
|
||||||
isVideoFileInfoHashValid,
|
isVideoFileInfoHashValid,
|
||||||
|
@ -149,7 +150,7 @@ export enum ScopeNames {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoFileModel extends Model {
|
export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel>>> {
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { afterCommitIfTransaction } from '@server/helpers/database-utils'
|
import { afterCommitIfTransaction } from '@server/helpers/database-utils'
|
||||||
import { MVideoImportDefault, MVideoImportFormattable } from '@server/types/models/video/video-import'
|
import { MVideoImportDefault, MVideoImportFormattable } from '@server/types/models/video/video-import'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoImport, VideoImportState } from '../../../shared'
|
import { VideoImport, VideoImportState } from '../../../shared'
|
||||||
import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../helpers/custom-validators/video-imports'
|
import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../helpers/custom-validators/video-imports'
|
||||||
import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos'
|
import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos'
|
||||||
|
@ -52,7 +53,7 @@ import { ScopeNames as VideoModelScopeNames, VideoModel } from './video'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoImportModel extends Model {
|
export class VideoImportModel extends Model<Partial<AttributesOnly<VideoImportModel>>> {
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, DefaultScope, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, DefaultScope, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
import { WEBSERVER } from '@server/initializers/constants'
|
import { WEBSERVER } from '@server/initializers/constants'
|
||||||
import { MVideoLive, MVideoLiveVideo } from '@server/types/models'
|
import { MVideoLive, MVideoLiveVideo } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { LiveVideo, VideoState } from '@shared/models'
|
import { LiveVideo, VideoState } from '@shared/models'
|
||||||
import { VideoModel } from './video'
|
import { VideoModel } from './video'
|
||||||
import { VideoBlacklistModel } from './video-blacklist'
|
import { VideoBlacklistModel } from './video-blacklist'
|
||||||
|
@ -28,7 +29,7 @@ import { VideoBlacklistModel } from './video-blacklist'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoLiveModel extends Model {
|
export class VideoLiveModel extends Model<Partial<AttributesOnly<VideoLiveModel>>> {
|
||||||
|
|
||||||
@AllowNull(true)
|
@AllowNull(true)
|
||||||
@Column(DataType.STRING)
|
@Column(DataType.STRING)
|
||||||
|
|
|
@ -32,6 +32,7 @@ import { AccountModel } from '../account/account'
|
||||||
import { getSort, throwIfNotValid } from '../utils'
|
import { getSort, throwIfNotValid } from '../utils'
|
||||||
import { ForAPIOptions, ScopeNames as VideoScopeNames, VideoModel } from './video'
|
import { ForAPIOptions, ScopeNames as VideoScopeNames, VideoModel } from './video'
|
||||||
import { VideoPlaylistModel } from './video-playlist'
|
import { VideoPlaylistModel } from './video-playlist'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
|
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'videoPlaylistElement',
|
tableName: 'videoPlaylistElement',
|
||||||
|
@ -48,7 +49,7 @@ import { VideoPlaylistModel } from './video-playlist'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoPlaylistElementModel extends Model {
|
export class VideoPlaylistElementModel extends Model<Partial<AttributesOnly<VideoPlaylistElementModel>>> {
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
@ -274,7 +275,8 @@ export class VideoPlaylistElementModel extends Model {
|
||||||
validate: false // We use a literal to update the position
|
validate: false // We use a literal to update the position
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoPlaylistElementModel.update({ position: Sequelize.literal(`${newPosition} + "position" - ${firstPosition}`) }, query)
|
const positionQuery = Sequelize.literal(`${newPosition} + "position" - ${firstPosition}`)
|
||||||
|
return VideoPlaylistElementModel.update({ position: positionQuery as any }, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
static increasePositionOf (
|
static increasePositionOf (
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
} from 'sequelize-typescript'
|
} from 'sequelize-typescript'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { MAccountId, MChannelId } from '@server/types/models'
|
import { MAccountId, MChannelId } from '@server/types/models'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { ActivityIconObject } from '../../../shared/models/activitypub/objects'
|
import { ActivityIconObject } from '../../../shared/models/activitypub/objects'
|
||||||
import { PlaylistObject } from '../../../shared/models/activitypub/objects/playlist-object'
|
import { PlaylistObject } from '../../../shared/models/activitypub/objects/playlist-object'
|
||||||
import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'
|
import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'
|
||||||
|
@ -221,7 +222,7 @@ type AvailableForListOptions = {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoPlaylistModel extends Model {
|
export class VideoPlaylistModel extends Model<Partial<AttributesOnly<VideoPlaylistModel>>> {
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { VideoFilter, VideoPrivacy, VideoState } from '@shared/models'
|
import { Sequelize } from 'sequelize/types'
|
||||||
import { buildDirectionAndField, createSafeIn } from '@server/models/utils'
|
|
||||||
import { Model } from 'sequelize-typescript'
|
|
||||||
import { MUserAccountId, MUserId } from '@server/types/models'
|
|
||||||
import validator from 'validator'
|
import validator from 'validator'
|
||||||
import { exists } from '@server/helpers/custom-validators/misc'
|
import { exists } from '@server/helpers/custom-validators/misc'
|
||||||
|
import { buildDirectionAndField, createSafeIn } from '@server/models/utils'
|
||||||
|
import { MUserAccountId, MUserId } from '@server/types/models'
|
||||||
|
import { VideoFilter, VideoPrivacy, VideoState } from '@shared/models'
|
||||||
|
|
||||||
export type BuildVideosQueryOptions = {
|
export type BuildVideosQueryOptions = {
|
||||||
attributes?: string[]
|
attributes?: string[]
|
||||||
|
@ -55,7 +55,7 @@ export type BuildVideosQueryOptions = {
|
||||||
having?: string
|
having?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildListQuery (model: typeof Model, options: BuildVideosQueryOptions) {
|
function buildListQuery (sequelize: Sequelize, options: BuildVideosQueryOptions) {
|
||||||
const and: string[] = []
|
const and: string[] = []
|
||||||
const joins: string[] = []
|
const joins: string[] = []
|
||||||
const replacements: any = {}
|
const replacements: any = {}
|
||||||
|
@ -77,7 +77,7 @@ function buildListQuery (model: typeof Model, options: BuildVideosQueryOptions)
|
||||||
const blockerIds = [ options.serverAccountId ]
|
const blockerIds = [ options.serverAccountId ]
|
||||||
if (options.user) blockerIds.push(options.user.Account.id)
|
if (options.user) blockerIds.push(options.user.Account.id)
|
||||||
|
|
||||||
const inClause = createSafeIn(model, blockerIds)
|
const inClause = createSafeIn(sequelize, blockerIds)
|
||||||
|
|
||||||
and.push(
|
and.push(
|
||||||
'NOT EXISTS (' +
|
'NOT EXISTS (' +
|
||||||
|
@ -179,7 +179,7 @@ function buildListQuery (model: typeof Model, options: BuildVideosQueryOptions)
|
||||||
'EXISTS (' +
|
'EXISTS (' +
|
||||||
' SELECT 1 FROM "videoTag" ' +
|
' SELECT 1 FROM "videoTag" ' +
|
||||||
' INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
|
' INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
|
||||||
' WHERE lower("tag"."name") IN (' + createSafeIn(model, tagsOneOfLower) + ') ' +
|
' WHERE lower("tag"."name") IN (' + createSafeIn(sequelize, tagsOneOfLower) + ') ' +
|
||||||
' AND "video"."id" = "videoTag"."videoId"' +
|
' AND "video"."id" = "videoTag"."videoId"' +
|
||||||
')'
|
')'
|
||||||
)
|
)
|
||||||
|
@ -192,7 +192,7 @@ function buildListQuery (model: typeof Model, options: BuildVideosQueryOptions)
|
||||||
'EXISTS (' +
|
'EXISTS (' +
|
||||||
' SELECT 1 FROM "videoTag" ' +
|
' SELECT 1 FROM "videoTag" ' +
|
||||||
' INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
|
' INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
|
||||||
' WHERE lower("tag"."name") IN (' + createSafeIn(model, tagsAllOfLower) + ') ' +
|
' WHERE lower("tag"."name") IN (' + createSafeIn(sequelize, tagsAllOfLower) + ') ' +
|
||||||
' AND "video"."id" = "videoTag"."videoId" ' +
|
' AND "video"."id" = "videoTag"."videoId" ' +
|
||||||
' GROUP BY "videoTag"."videoId" HAVING COUNT(*) = ' + tagsAllOfLower.length +
|
' GROUP BY "videoTag"."videoId" HAVING COUNT(*) = ' + tagsAllOfLower.length +
|
||||||
')'
|
')'
|
||||||
|
@ -232,7 +232,7 @@ function buildListQuery (model: typeof Model, options: BuildVideosQueryOptions)
|
||||||
languagesQueryParts.push(
|
languagesQueryParts.push(
|
||||||
'EXISTS (' +
|
'EXISTS (' +
|
||||||
' SELECT 1 FROM "videoCaption" WHERE "videoCaption"."language" ' +
|
' SELECT 1 FROM "videoCaption" WHERE "videoCaption"."language" ' +
|
||||||
' IN (' + createSafeIn(model, languages) + ') AND ' +
|
' IN (' + createSafeIn(sequelize, languages) + ') AND ' +
|
||||||
' "videoCaption"."videoId" = "video"."id"' +
|
' "videoCaption"."videoId" = "video"."id"' +
|
||||||
')'
|
')'
|
||||||
)
|
)
|
||||||
|
@ -345,8 +345,8 @@ function buildListQuery (model: typeof Model, options: BuildVideosQueryOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.search) {
|
if (options.search) {
|
||||||
const escapedSearch = model.sequelize.escape(options.search)
|
const escapedSearch = sequelize.escape(options.search)
|
||||||
const escapedLikeSearch = model.sequelize.escape('%' + options.search + '%')
|
const escapedLikeSearch = sequelize.escape('%' + options.search + '%')
|
||||||
|
|
||||||
cte.push(
|
cte.push(
|
||||||
'"trigramSearch" AS (' +
|
'"trigramSearch" AS (' +
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { literal, Op, QueryTypes, Transaction } from 'sequelize'
|
import { literal, Op, QueryTypes, Transaction } from 'sequelize'
|
||||||
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
||||||
import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
|
import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
|
||||||
import { MActorDefault } from '../../types/models'
|
import { MActorDefault } from '../../types/models'
|
||||||
|
@ -50,7 +51,7 @@ enum ScopeNames {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoShareModel extends Model {
|
export class VideoShareModel extends Model<Partial<AttributesOnly<VideoShareModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Is('VideoShareUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url'))
|
@Is('VideoShareUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url'))
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { CONSTRAINTS_FIELDS, MEMOIZE_LENGTH, MEMOIZE_TTL, P2P_MEDIA_LOADER_PEER_
|
||||||
import { VideoRedundancyModel } from '../redundancy/video-redundancy'
|
import { VideoRedundancyModel } from '../redundancy/video-redundancy'
|
||||||
import { throwIfNotValid } from '../utils'
|
import { throwIfNotValid } from '../utils'
|
||||||
import { VideoModel } from './video'
|
import { VideoModel } from './video'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
|
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'videoStreamingPlaylist',
|
tableName: 'videoStreamingPlaylist',
|
||||||
|
@ -30,7 +31,7 @@ import { VideoModel } from './video'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoStreamingPlaylistModel extends Model {
|
export class VideoStreamingPlaylistModel extends Model<Partial<AttributesOnly<VideoStreamingPlaylistModel>>> {
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
import { Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { TagModel } from './tag'
|
import { TagModel } from './tag'
|
||||||
import { VideoModel } from './video'
|
import { VideoModel } from './video'
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ import { VideoModel } from './video'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoTagModel extends Model {
|
export class VideoTagModel extends Model<Partial<AttributesOnly<VideoTagModel>>> {
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Table } from 'sequelize-typescript'
|
|
||||||
import { VideoModel } from './video'
|
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
|
import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Table } from 'sequelize-typescript'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
|
import { VideoModel } from './video'
|
||||||
|
|
||||||
@Table({
|
@Table({
|
||||||
tableName: 'videoView',
|
tableName: 'videoView',
|
||||||
|
@ -14,7 +15,7 @@ import * as Sequelize from 'sequelize'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoViewModel extends Model {
|
export class VideoViewModel extends Model<Partial<AttributesOnly<VideoViewModel>>> {
|
||||||
@CreatedAt
|
@CreatedAt
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import { LiveManager } from '@server/lib/live-manager'
|
||||||
import { getHLSDirectory, getVideoFilePath } from '@server/lib/video-paths'
|
import { getHLSDirectory, getVideoFilePath } from '@server/lib/video-paths'
|
||||||
import { getServerActor } from '@server/models/application/application'
|
import { getServerActor } from '@server/models/application/application'
|
||||||
import { ModelCache } from '@server/models/model-cache'
|
import { ModelCache } from '@server/models/model-cache'
|
||||||
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
import { VideoFile } from '@shared/models/videos/video-file.model'
|
import { VideoFile } from '@shared/models/videos/video-file.model'
|
||||||
import { ResultList, UserRight, VideoPrivacy, VideoState } from '../../../shared'
|
import { ResultList, UserRight, VideoPrivacy, VideoState } from '../../../shared'
|
||||||
import { VideoObject } from '../../../shared/models/activitypub/objects'
|
import { VideoObject } from '../../../shared/models/activitypub/objects'
|
||||||
|
@ -489,7 +490,7 @@ export type AvailableForListIDsOptions = {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class VideoModel extends Model {
|
export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
|
||||||
|
|
||||||
@AllowNull(false)
|
@AllowNull(false)
|
||||||
@Default(DataType.UUIDV4)
|
@Default(DataType.UUIDV4)
|
||||||
|
@ -1617,7 +1618,7 @@ export class VideoModel extends Model {
|
||||||
includeLocalVideos: true
|
includeLocalVideos: true
|
||||||
}
|
}
|
||||||
|
|
||||||
const { query, replacements } = buildListQuery(VideoModel, queryOptions)
|
const { query, replacements } = buildListQuery(VideoModel.sequelize, queryOptions)
|
||||||
|
|
||||||
return this.sequelize.query<any>(query, { replacements, type: QueryTypes.SELECT })
|
return this.sequelize.query<any>(query, { replacements, type: QueryTypes.SELECT })
|
||||||
.then(rows => rows.map(r => r[field]))
|
.then(rows => rows.map(r => r[field]))
|
||||||
|
@ -1645,7 +1646,7 @@ export class VideoModel extends Model {
|
||||||
if (countVideos !== true) return Promise.resolve(undefined)
|
if (countVideos !== true) return Promise.resolve(undefined)
|
||||||
|
|
||||||
const countOptions = Object.assign({}, options, { isCount: true })
|
const countOptions = Object.assign({}, options, { isCount: true })
|
||||||
const { query: queryCount, replacements: replacementsCount } = buildListQuery(VideoModel, countOptions)
|
const { query: queryCount, replacements: replacementsCount } = buildListQuery(VideoModel.sequelize, countOptions)
|
||||||
|
|
||||||
return VideoModel.sequelize.query<any>(queryCount, { replacements: replacementsCount, type: QueryTypes.SELECT })
|
return VideoModel.sequelize.query<any>(queryCount, { replacements: replacementsCount, type: QueryTypes.SELECT })
|
||||||
.then(rows => rows.length !== 0 ? rows[0].total : 0)
|
.then(rows => rows.length !== 0 ? rows[0].total : 0)
|
||||||
|
@ -1654,7 +1655,7 @@ export class VideoModel extends Model {
|
||||||
function getModels () {
|
function getModels () {
|
||||||
if (options.count === 0) return Promise.resolve([])
|
if (options.count === 0) return Promise.resolve([])
|
||||||
|
|
||||||
const { query, replacements, order } = buildListQuery(VideoModel, options)
|
const { query, replacements, order } = buildListQuery(VideoModel.sequelize, options)
|
||||||
const queryModels = wrapForAPIResults(query, replacements, options, order)
|
const queryModels = wrapForAPIResults(query, replacements, options, order)
|
||||||
|
|
||||||
return VideoModel.sequelize.query<any>(queryModels, { replacements, type: QueryTypes.SELECT, nest: true })
|
return VideoModel.sequelize.query<any>(queryModels, { replacements, type: QueryTypes.SELECT, nest: true })
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Model } from 'sequelize-typescript'
|
import { AttributesOnly } from '@shared/core-utils'
|
||||||
|
import { Model } from 'sequelize'
|
||||||
|
|
||||||
// Thanks to sequelize-typescript: https://github.com/RobinBuschmann/sequelize-typescript
|
// Thanks to sequelize-typescript: https://github.com/RobinBuschmann/sequelize-typescript
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ export type Omit<T, K extends keyof T> = { [P in Diff<keyof T, K>]: T[P] }
|
||||||
|
|
||||||
export type RecursivePartial<T> = { [P in keyof T]?: RecursivePartial<T[P]> }
|
export type RecursivePartial<T> = { [P in keyof T]?: RecursivePartial<T[P]> }
|
||||||
|
|
||||||
export type FilteredModelAttributes<T extends Model<T>> = RecursivePartial<Omit<T, keyof Model<any>>> & {
|
export type FilteredModelAttributes<T extends Model<any>> = Partial<AttributesOnly<T>> & {
|
||||||
id?: number | any
|
id?: number | any
|
||||||
createdAt?: Date | any
|
createdAt?: Date | any
|
||||||
updatedAt?: Date | any
|
updatedAt?: Date | any
|
||||||
|
|
|
@ -6,6 +6,10 @@ export type FunctionPropertyNames<T> = {
|
||||||
|
|
||||||
export type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>
|
export type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>
|
||||||
|
|
||||||
|
export type AttributesOnly<T> = {
|
||||||
|
[K in keyof T]: T[K] extends Function ? never : T[K]
|
||||||
|
}
|
||||||
|
|
||||||
export type PickWith<T, KT extends keyof T, V> = {
|
export type PickWith<T, KT extends keyof T, V> = {
|
||||||
[P in KT]: T[P] extends V ? V : never
|
[P in KT]: T[P] extends V ? V : never
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue