Stronger model typings
[oweals/peertube.git] / server / models / video / video-change-ownership.ts
1 import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
2 import { AccountModel } from '../account/account'
3 import { ScopeNames as VideoScopeNames, VideoModel } from './video'
4 import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '../../../shared/models/videos'
5 import { getSort } from '../utils'
6 import { MVideoChangeOwnershipFull } from '@server/typings/models/video/video-change-ownership'
7 import * as Bluebird from 'bluebird'
8
9 enum ScopeNames {
10   WITH_ACCOUNTS = 'WITH_ACCOUNTS',
11   WITH_VIDEO = 'WITH_VIDEO'
12 }
13
14 @Table({
15   tableName: 'videoChangeOwnership',
16   indexes: [
17     {
18       fields: [ 'videoId' ]
19     },
20     {
21       fields: [ 'initiatorAccountId' ]
22     },
23     {
24       fields: [ 'nextOwnerAccountId' ]
25     }
26   ]
27 })
28 @Scopes(() => ({
29   [ScopeNames.WITH_ACCOUNTS]: {
30     include: [
31       {
32         model: AccountModel,
33         as: 'Initiator',
34         required: true
35       },
36       {
37         model: AccountModel,
38         as: 'NextOwner',
39         required: true
40       }
41     ]
42   },
43   [ScopeNames.WITH_VIDEO]: {
44     include: [
45       {
46         model: VideoModel.scope([ VideoScopeNames.WITH_THUMBNAILS, VideoScopeNames.WITH_FILES ]),
47         required: true
48       }
49     ]
50   }
51 }))
52 export class VideoChangeOwnershipModel extends Model<VideoChangeOwnershipModel> {
53   @CreatedAt
54   createdAt: Date
55
56   @UpdatedAt
57   updatedAt: Date
58
59   @AllowNull(false)
60   @Column
61   status: VideoChangeOwnershipStatus
62
63   @ForeignKey(() => AccountModel)
64   @Column
65   initiatorAccountId: number
66
67   @BelongsTo(() => AccountModel, {
68     foreignKey: {
69       name: 'initiatorAccountId',
70       allowNull: false
71     },
72     onDelete: 'cascade'
73   })
74   Initiator: AccountModel
75
76   @ForeignKey(() => AccountModel)
77   @Column
78   nextOwnerAccountId: number
79
80   @BelongsTo(() => AccountModel, {
81     foreignKey: {
82       name: 'nextOwnerAccountId',
83       allowNull: false
84     },
85     onDelete: 'cascade'
86   })
87   NextOwner: AccountModel
88
89   @ForeignKey(() => VideoModel)
90   @Column
91   videoId: number
92
93   @BelongsTo(() => VideoModel, {
94     foreignKey: {
95       allowNull: false
96     },
97     onDelete: 'cascade'
98   })
99   Video: VideoModel
100
101   static listForApi (nextOwnerId: number, start: number, count: number, sort: string) {
102     const query = {
103       offset: start,
104       limit: count,
105       order: getSort(sort),
106       where: {
107         nextOwnerAccountId: nextOwnerId
108       }
109     }
110
111     return Promise.all([
112       VideoChangeOwnershipModel.scope(ScopeNames.WITH_ACCOUNTS).count(query),
113       VideoChangeOwnershipModel.scope([ ScopeNames.WITH_ACCOUNTS, ScopeNames.WITH_VIDEO ]).findAll<MVideoChangeOwnershipFull>(query)
114     ]).then(([ count, rows ]) => ({ total: count, data: rows }))
115   }
116
117   static load (id: number): Bluebird<MVideoChangeOwnershipFull> {
118     return VideoChangeOwnershipModel.scope([ ScopeNames.WITH_ACCOUNTS, ScopeNames.WITH_VIDEO ])
119                                     .findByPk(id)
120   }
121
122   toFormattedJSON (): VideoChangeOwnership {
123     return {
124       id: this.id,
125       status: this.status,
126       initiatorAccount: this.Initiator.toFormattedJSON(),
127       nextOwnerAccount: this.NextOwner.toFormattedJSON(),
128       video: {
129         id: this.Video.id,
130         uuid: this.Video.uuid,
131         url: this.Video.url,
132         name: this.Video.name
133       },
134       createdAt: this.createdAt
135     }
136   }
137 }