Update sequelize
authorChocobozzz <me@florianbigard.com>
Thu, 18 Apr 2019 09:28:17 +0000 (11:28 +0200)
committerChocobozzz <me@florianbigard.com>
Wed, 24 Apr 2019 14:26:20 +0000 (16:26 +0200)
46 files changed:
package.json
server/controllers/api/videos/import.ts
server/controllers/api/videos/index.ts
server/helpers/database-utils.ts
server/initializers/database.ts
server/initializers/migrations/0080-video-channels.ts
server/initializers/migrations/0100-activitypub.ts
server/initializers/migrations/0135-video-channel-actor.ts
server/initializers/migrations/0345-video-playlists.ts
server/initializers/migrator.ts
server/lib/activitypub/cache-file.ts
server/lib/activitypub/playlist.ts
server/lib/activitypub/process/process-follow.ts
server/lib/activitypub/process/process-update.ts
server/lib/activitypub/video-comments.ts
server/lib/activitypub/video-rates.ts
server/lib/activitypub/videos.ts
server/lib/user.ts
server/lib/video-comment.ts
server/models/account/account-video-rate.ts
server/models/account/account.ts
server/models/account/user-notification.ts
server/models/account/user-video-history.ts
server/models/account/user.ts
server/models/activitypub/actor-follow.ts
server/models/activitypub/actor.ts
server/models/migrations.ts
server/models/oauth/oauth-client.ts
server/models/oauth/oauth-token.ts
server/models/redundancy/video-redundancy.ts
server/models/utils.ts
server/models/video/schedule-video-update.ts
server/models/video/tag.ts
server/models/video/video-abuse.ts
server/models/video/video-blacklist.ts
server/models/video/video-caption.ts
server/models/video/video-change-ownership.ts
server/models/video/video-channel.ts
server/models/video/video-comment.ts
server/models/video/video-import.ts
server/models/video/video-playlist-element.ts
server/models/video/video-playlist.ts
server/models/video/video-streaming-playlist.ts
server/models/video/video.ts
shared/extra-utils/miscs/sql.ts
yarn.lock

index 6b39862787611f4b21d9334acfb8ae0c21ee8e60..20cbd555ad5a3ff509b73cb047e6c9af0fc1286b 100644 (file)
     "reflect-metadata": "^0.1.12",
     "request": "^2.81.0",
     "scripty": "^1.5.0",
-    "sequelize": "4.42.0",
-    "sequelize-typescript": "0.6.7",
+    "sequelize": "5.6.1",
+    "sequelize-typescript": "^1.0.0-beta.1",
     "sharp": "^0.22.0",
     "sitemap": "^2.1.0",
     "socket.io": "^2.2.0",
index f9a24a0c2c7c628af9f70f708593df6735dac956..a4ec41d443fed6fb62ddc2436b965f8cfd67e244 100644 (file)
@@ -15,7 +15,6 @@ import { VideoImportModel } from '../../../models/video/video-import'
 import { JobQueue } from '../../../lib/job-queue/job-queue'
 import { join } from 'path'
 import { isArray } from '../../../helpers/custom-validators/misc'
-import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model'
 import { VideoChannelModel } from '../../../models/video/video-channel'
 import * as Bluebird from 'bluebird'
 import * as parseTorrent from 'parse-torrent'
@@ -228,7 +227,7 @@ function insertIntoDB (parameters: {
   previewModel: ThumbnailModel,
   videoChannel: VideoChannelModel,
   tags: string[],
-  videoImportAttributes: FilteredModelAttributes<VideoImportModel>
+  videoImportAttributes: Partial<VideoImportModel>
 }): Bluebird<VideoImportModel> {
   let { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes } = parameters
 
index 24721a17fa5be35dd65ce13cb9e95a4ae360f352..ad2fe958c215c12c3b6fc641519b8cf6afec510c 100644 (file)
@@ -332,15 +332,15 @@ async function updateVideo (req: express.Request, res: express.Response) {
       if (videoInfoToUpdate.downloadEnabled !== undefined) videoInstance.set('downloadEnabled', videoInfoToUpdate.downloadEnabled)
 
       if (videoInfoToUpdate.originallyPublishedAt !== undefined && videoInfoToUpdate.originallyPublishedAt !== null) {
-        videoInstance.set('originallyPublishedAt', videoInfoToUpdate.originallyPublishedAt)
+        videoInstance.originallyPublishedAt = new Date(videoInfoToUpdate.originallyPublishedAt)
       }
 
       if (videoInfoToUpdate.privacy !== undefined) {
         const newPrivacy = parseInt(videoInfoToUpdate.privacy.toString(), 10)
-        videoInstance.set('privacy', newPrivacy)
+        videoInstance.privacy = newPrivacy
 
         if (wasPrivateVideo === true && newPrivacy !== VideoPrivacy.PRIVATE) {
-          videoInstance.set('publishedAt', new Date())
+          videoInstance.publishedAt = new Date()
         }
       }
 
index 1005d2cf19694f16e3f0cf1f000834a9c3a83972..39c74b2fdec9d87e791abb3de9be7b44dbc19083 100644 (file)
@@ -62,14 +62,13 @@ function updateInstanceWithAnother <T extends Model<T>> (instanceToUpdate: Model
   const obj = baseInstance.toJSON()
 
   for (const key of Object.keys(obj)) {
-    instanceToUpdate.set(key, obj[key])
+    instanceToUpdate[key] = obj[key]
   }
 }
 
 function resetSequelizeInstance (instance: Model<any>, savedFields: object) {
   Object.keys(savedFields).forEach(key => {
-    const value = savedFields[key]
-    instance.set(key, value)
+    instance[key] = savedFields[key]
   })
 }
 
index 8f237eb23b48a02a6b290363a2d11c4ebdd52f4b..d1744d21ffba180a6b01afc7787b8ae5b35eeec4 100644 (file)
@@ -37,6 +37,7 @@ import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-pla
 import { VideoPlaylistModel } from '../models/video/video-playlist'
 import { VideoPlaylistElementModel } from '../models/video/video-playlist-element'
 import { ThumbnailModel } from '../models/video/thumbnail'
+import { QueryTypes, Transaction } from 'sequelize'
 
 require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string
 
@@ -58,8 +59,7 @@ const sequelizeTypescript = new SequelizeTypescript({
     max: poolMax
   },
   benchmark: isTestInstance(),
-  isolationLevel: SequelizeTypescript.Transaction.ISOLATION_LEVELS.SERIALIZABLE,
-  operatorsAliases: false,
+  isolationLevel: Transaction.ISOLATION_LEVELS.SERIALIZABLE,
   logging: (message: string, benchmark: number) => {
     if (process.env.NODE_DB_LOG === 'false') return
 
@@ -141,10 +141,15 @@ async function checkPostgresExtensions () {
 
 async function checkPostgresExtension (extension: string) {
   const query = `SELECT true AS enabled FROM pg_available_extensions WHERE name = '${extension}' AND installed_version IS NOT NULL;`
-  const [ res ] = await sequelizeTypescript.query(query, { raw: true })
+  const options = {
+    type: QueryTypes.SELECT as QueryTypes.SELECT,
+    raw: true
+  }
+
+  const res = await sequelizeTypescript.query<{ enabled: boolean }>(query, options)
 
   if (!res || res.length === 0 || res[ 0 ][ 'enabled' ] !== true) {
-    // Try to create the extension ourself
+    // Try to create the extension ourselves
     try {
       await sequelizeTypescript.query(`CREATE EXTENSION ${extension};`, { raw: true })
 
index 0e17a4ccde72937b3b4d93eb25401435d65ff527..5512bdcf1593a739ddd4d6b9e1e994fba337aecb 100644 (file)
@@ -69,7 +69,7 @@ async function up (utils: {
   const options = {
     type: Sequelize.QueryTypes.SELECT
   }
-  const rawVideos = await utils.sequelize.query(query, options)
+  const rawVideos = await utils.sequelize.query(query, options) as any
 
   for (const rawVideo of rawVideos) {
     const videoChannel = await utils.db.VideoChannel.findOne({ where: { authorId: rawVideo.authorId } })
index a7ebd804cd51e82447c2d5298b8378c9faeab7ec..2880a97d9da18656a6273e8671a2796d61ffa2ee 100644 (file)
@@ -21,7 +21,7 @@ async function up (utils: {
     const options = {
       type: Sequelize.QueryTypes.SELECT
     }
-    const res = await utils.sequelize.query(query, options)
+    const res = await utils.sequelize.query(query, options) as any
 
     if (!res[0] || res[0].total !== 0) {
       throw new Error('You need to quit friends.')
@@ -68,8 +68,8 @@ async function up (utils: {
     const accountCreated = await createLocalAccountWithoutKeys(SERVER_ACTOR_NAME, null, applicationInstance.id, undefined)
 
     const { publicKey, privateKey } = await createPrivateAndPublicKeys()
-    accountCreated.set('publicKey', publicKey)
-    accountCreated.set('privateKey', privateKey)
+    accountCreated.Actor.publicKey = publicKey
+    accountCreated.Actor.privateKey = privateKey
 
     await accountCreated.save()
   }
@@ -86,8 +86,8 @@ async function up (utils: {
     const account = await createLocalAccountWithoutKeys(user.username, user.id, null, undefined)
 
     const { publicKey, privateKey } = await createPrivateAndPublicKeys()
-    account.set('publicKey', publicKey)
-    account.set('privateKey', privateKey)
+    account.Actor.publicKey = publicKey
+    account.Actor.privateKey = privateKey
     await account.save()
   }
 
index 033f43b681954f8a45da098159d280179d27281f..5ace0f4d27dcdc3e8126ad122005abe333759bab 100644 (file)
@@ -239,7 +239,8 @@ async function up (utils: {
 
   {
     const query = 'SELECT * FROM "actor" WHERE "serverId" IS NULL AND "publicKey" IS NULL'
-    const [ res ] = await utils.sequelize.query(query)
+    const options = { type: Sequelize.QueryTypes.SELECT as Sequelize.QueryTypes.SELECT }
+    const [ res ] = await utils.sequelize.query(query, options)
 
     for (const actor of res) {
       const { privateKey, publicKey } = await createPrivateAndPublicKeys()
index 6953f555322be2835773cc440ecab12391e9271e..de69f5b9ea5c3e9d645e840ea032fb5091ab655e 100644 (file)
@@ -51,7 +51,9 @@ CREATE TABLE IF NOT EXISTS "videoPlaylistElement"
 
   {
     const userQuery = 'SELECT "username" FROM "user";'
-    const userResult = await utils.sequelize.query(userQuery, { transaction, type: Sequelize.QueryTypes.SELECT })
+
+    const options = { transaction, type: Sequelize.QueryTypes.SELECT as Sequelize.QueryTypes.SELECT }
+    const userResult = await utils.sequelize.query<{ username: string }>(userQuery, options)
     const usernames = userResult.map(r => r.username)
 
     for (const username of usernames) {
index adc2f9fb370ddd9f15ddbd4838a2b5d6be6cac13..1cb0116b7bfc145633e6baf1b2bb3fac294dc503 100644 (file)
@@ -3,6 +3,7 @@ import { logger } from '../helpers/logger'
 import { LAST_MIGRATION_VERSION } from './constants'
 import { sequelizeTypescript } from './database'
 import { readdir } from 'fs-extra'
+import { QueryTypes } from 'sequelize'
 
 async function migrate () {
   const tables = await sequelizeTypescript.getQueryInterface().showAllTables()
@@ -13,7 +14,12 @@ async function migrate () {
 
   let actualVersion: number | null = null
 
-  const [ rows ] = await sequelizeTypescript.query('SELECT "migrationVersion" FROM "application"')
+  const query = 'SELECT "migrationVersion" FROM "application"'
+  const options = {
+    type: QueryTypes.SELECT as QueryTypes.SELECT
+  }
+
+  const rows = await sequelizeTypescript.query<{ migrationVersion: number }>(query, options)
   if (rows && rows[0] && rows[0].migrationVersion) {
     actualVersion = rows[0].migrationVersion
   }
index 59700313568e5ecda12346b5a62b172b7b072155..de5cc54accc5fddf9677cb40888a2914a5fa5b12 100644 (file)
@@ -68,8 +68,8 @@ function updateCacheFile (
 
   const attributes = cacheFileActivityObjectToDBAttributes(cacheFileObject, video, byActor)
 
-  redundancyModel.set('expires', attributes.expiresOn)
-  redundancyModel.set('fileUrl', attributes.fileUrl)
+  redundancyModel.expiresOn = attributes.expiresOn
+  redundancyModel.fileUrl = attributes.fileUrl
 
   return redundancyModel.save({ transaction: t })
 }
index 341e469f3ff8bb0777eb1808d13ddc94f81d0b1f..721c19603b46f52b1e25fd44bb0a7e2c84de175a 100644 (file)
@@ -14,7 +14,6 @@ import { getOrCreateVideoAndAccountAndChannel } from './videos'
 import { isPlaylistElementObjectValid, isPlaylistObjectValid } from '../../helpers/custom-validators/activitypub/playlist'
 import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element'
 import { VideoModel } from '../../models/video/video'
-import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model'
 import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'
 import { sequelizeTypescript } from '../../initializers/database'
 import { createPlaylistThumbnailFromUrl } from '../thumbnail'
@@ -87,7 +86,8 @@ async function createOrUpdateVideoPlaylist (playlistObject: PlaylistObject, byAc
     }
   }
 
-  const [ playlist ] = await VideoPlaylistModel.upsert<VideoPlaylistModel>(playlistAttributes, { returning: true })
+  // FIXME: sequelize typings
+  const [ playlist ] = (await VideoPlaylistModel.upsert<VideoPlaylistModel>(playlistAttributes, { returning: true }) as any)
 
   let accItems: string[] = []
   await crawlCollectionPage<string>(playlistObject.id, items => {
@@ -156,7 +156,7 @@ export {
 // ---------------------------------------------------------------------------
 
 async function resetVideoPlaylistElements (elementUrls: string[], playlist: VideoPlaylistModel) {
-  const elementsToCreate: FilteredModelAttributes<VideoPlaylistElementModel>[] = []
+  const elementsToCreate: object[] = [] // FIXME: sequelize typings
 
   await Bluebird.map(elementUrls, async elementUrl => {
     try {
index ac3dd6ac403b8b4e4c29dc3848fa91cf01b0197a..ed16ba172688d5f11d1d3aeade1439706b766f94 100644 (file)
@@ -37,7 +37,9 @@ async function processFollow (actor: ActorModel, targetActorURL: string) {
     if (isFollowingInstance && CONFIG.FOLLOWERS.INSTANCE.ENABLED === false) {
       logger.info('Rejecting %s because instance followers are disabled.', targetActor.url)
 
-      return sendReject(actor, targetActor)
+      await sendReject(actor, targetActor)
+
+      return { actorFollow: undefined }
     }
 
     const [ actorFollow, created ] = await ActorFollowModel.findOrCreate({
index 0b96ba3526593b731f607fab94fd25b661911dda..54a9234bb16c0740fd111caa1b40ff281adbb419 100644 (file)
@@ -120,9 +120,11 @@ async function processUpdateActor (actor: ActorModel, activity: ActivityUpdate)
 
       await actor.save({ transaction: t })
 
-      accountOrChannelInstance.set('name', actorAttributesToUpdate.name || actorAttributesToUpdate.preferredUsername)
-      accountOrChannelInstance.set('description', actorAttributesToUpdate.summary)
-      accountOrChannelInstance.set('support', actorAttributesToUpdate.support)
+      accountOrChannelInstance.name = actorAttributesToUpdate.name || actorAttributesToUpdate.preferredUsername
+      accountOrChannelInstance.description = actorAttributesToUpdate.summary
+
+      if (accountOrChannelInstance instanceof VideoChannelModel) accountOrChannelInstance.support = actorAttributesToUpdate.support
+
       await accountOrChannelInstance.save({ transaction: t })
     })
 
index 18f44d50ecbee4bfb1aaca7efd61809a1a20a3a9..cb67bf9a49320c451e40aff7c16df0663b492eb2 100644 (file)
@@ -73,7 +73,8 @@ async function addVideoComment (videoInstance: VideoModel, commentUrl: string) {
   const entry = await videoCommentActivityObjectToDBAttributes(videoInstance, actor, body)
   if (!entry) return { created: false }
 
-  const [ comment, created ] = await VideoCommentModel.upsert<VideoCommentModel>(entry, { returning: true })
+  // FIXME: sequelize typings
+  const [ comment, created ] = (await VideoCommentModel.upsert<VideoCommentModel>(entry, { returning: true }) as any)
   comment.Account = actor.Account
   comment.Video = videoInstance
 
index 7809c58b868869680e0e90fc51d20868246f1e7a..cda5b2981da1d523d7f3b249f40f3ff03abaf580 100644 (file)
@@ -56,7 +56,10 @@ async function createRates (ratesUrl: string[], video: VideoModel, rate: VideoRa
   logger.info('Adding %d %s to video %s.', rateCounts, rate, video.uuid)
 
   // This is "likes" and "dislikes"
-  if (rateCounts !== 0) await video.increment(rate + 's', { by: rateCounts })
+  if (rateCounts !== 0) {
+    const field = rate === 'like' ? 'likes' : 'dislikes'
+    await video.increment(field, { by: rateCounts })
+  }
 
   return
 }
index 16c37a55fc35ab5008a2c1fb1a23bffc20e7e087..5a56942a94ca960d89a1c52f0ccf655029f95f78 100644 (file)
@@ -6,7 +6,7 @@ import {
   ActivityPlaylistSegmentHashesObject,
   ActivityPlaylistUrlObject,
   ActivityUrlObject,
-  ActivityVideoUrlObject, VideoCreate,
+  ActivityVideoUrlObject,
   VideoState
 } from '../../../shared/index'
 import { VideoTorrentObject } from '../../../shared/models/activitypub/objects'
@@ -45,7 +45,6 @@ import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub'
 import { Notifier } from '../notifier'
 import { VideoStreamingPlaylistModel } from '../../models/video/video-streaming-playlist'
 import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type'
-import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model'
 import { AccountVideoRateModel } from '../../models/account/account-video-rate'
 import { VideoShareModel } from '../../models/video/video-share'
 import { VideoCommentModel } from '../../models/video/video-comment'
@@ -312,7 +311,7 @@ async function updateVideoFromAP (options: {
 
         // Update or add other one
         const upsertTasks = videoFileAttributes.map(a => {
-          return VideoFileModel.upsert<VideoFileModel>(a, { returning: true, transaction: t })
+          return (VideoFileModel.upsert<VideoFileModel>(a, { returning: true, transaction: t }) as any) // FIXME: sequelize typings
             .then(([ file ]) => file)
         })
 
@@ -335,7 +334,8 @@ async function updateVideoFromAP (options: {
 
         // Update or add other one
         const upsertTasks = streamingPlaylistAttributes.map(a => {
-          return VideoStreamingPlaylistModel.upsert<VideoStreamingPlaylistModel>(a, { returning: true, transaction: t })
+          // FIXME: sequelize typings
+          return (VideoStreamingPlaylistModel.upsert<VideoStreamingPlaylistModel>(a, { returning: true, transaction: t }) as any)
                                .then(([ streamingPlaylist ]) => streamingPlaylist)
         })
 
@@ -594,7 +594,7 @@ function videoFileActivityUrlToDBAttributes (video: VideoModel, videoObject: Vid
     throw new Error('Cannot find video files for ' + video.url)
   }
 
-  const attributes: FilteredModelAttributes<VideoFileModel>[] = []
+  const attributes: object[] = [] // FIXME: add typings
   for (const fileUrl of fileUrls) {
     // Fetch associated magnet uri
     const magnet = videoObject.url.find(u => {
@@ -629,7 +629,7 @@ function streamingPlaylistActivityUrlToDBAttributes (video: VideoModel, videoObj
   const playlistUrls = videoObject.url.filter(u => isAPStreamingPlaylistUrlObject(u)) as ActivityPlaylistUrlObject[]
   if (playlistUrls.length === 0) return []
 
-  const attributes: FilteredModelAttributes<VideoStreamingPlaylistModel>[] = []
+  const attributes: object[] = [] // FIXME: add typings
   for (const playlistUrlObject of playlistUrls) {
     const segmentsSha256UrlObject = playlistUrlObject.tag
                                                      .find(t => {
index ce0d60518f67e253fcb50b6b4215809339c17dec..7badb3e72e41c2d4dadc0cfdbd0a674428c502e0 100644 (file)
@@ -7,7 +7,6 @@ import { UserModel } from '../models/account/user'
 import { buildActorInstance, getAccountActivityPubUrl, setAsyncActorKeys } from './activitypub'
 import { createVideoChannel } from './video-channel'
 import { VideoChannelModel } from '../models/video/video-channel'
-import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model'
 import { ActorModel } from '../models/activitypub/actor'
 import { UserNotificationSettingModel } from '../models/account/user-notification-setting'
 import { UserNotificationSetting, UserNotificationSettingValue } from '../../shared/models/users'
@@ -73,7 +72,7 @@ async function createLocalAccountWithoutKeys (
     userId,
     applicationId,
     actorId: actorInstanceCreated.id
-  } as FilteredModelAttributes<AccountModel>)
+  })
 
   const accountInstanceCreated = await accountInstance.save({ transaction: t })
   accountInstanceCreated.Actor = actorInstanceCreated
index 59bce7520af4c1732988d49b81f6f0347123413d..bfe22d225b88ecfb7b7b3aa6846f2e35c41b492c 100644 (file)
@@ -28,7 +28,7 @@ async function createVideoComment (obj: {
     videoId: obj.video.id,
     accountId: obj.account.id,
     url: 'fake url'
-  }, { transaction: t, validate: false })
+  }, { transaction: t, validate: false } as any) // FIXME: sequelize typings
 
   comment.set('url', getVideoCommentActivityPubUrl(obj.video, comment))
 
index 78a897a65a738693e21585849f67a6425f6f3c62..59f586b5464db878a1559762260133cb373a95f0 100644 (file)
@@ -1,16 +1,15 @@
 import { values } from 'lodash'
-import { Transaction, Op } from 'sequelize'
+import { FindOptions, Op, Transaction } from 'sequelize'
 import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
-import { IFindOptions } from 'sequelize-typescript/lib/interfaces/IFindOptions'
 import { VideoRateType } from '../../../shared/models/videos'
 import { CONSTRAINTS_FIELDS, VIDEO_RATE_TYPES } from '../../initializers/constants'
 import { VideoModel } from '../video/video'
 import { AccountModel } from './account'
 import { ActorModel } from '../activitypub/actor'
-import { throwIfNotValid, getSort } from '../utils'
+import { getSort, throwIfNotValid } from '../utils'
 import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
 import { AccountVideoRate } from '../../../shared'
-import { VideoChannelModel, ScopeNames as VideoChannelScopeNames } from '../video/video-channel'
+import { ScopeNames as VideoChannelScopeNames, VideoChannelModel } from '../video/video-channel'
 
 /*
   Account rates per video.
@@ -40,7 +39,7 @@ import { VideoChannelModel, ScopeNames as VideoChannelScopeNames } from '../vide
 export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
 
   @AllowNull(false)
-  @Column(DataType.ENUM(values(VIDEO_RATE_TYPES)))
+  @Column(DataType.ENUM(...values(VIDEO_RATE_TYPES)))
   type: VideoRateType
 
   @AllowNull(false)
@@ -79,7 +78,7 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
   Account: AccountModel
 
   static load (accountId: number, videoId: number, transaction?: Transaction) {
-    const options: IFindOptions<AccountVideoRateModel> = {
+    const options: FindOptions = {
       where: {
         accountId,
         videoId
@@ -97,7 +96,7 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
     type?: string,
     accountId: number
   }) {
-    const query: IFindOptions<AccountVideoRateModel> = {
+    const query: FindOptions = {
       offset: options.start,
       limit: options.count,
       order: getSort(options.sort),
@@ -123,7 +122,7 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
   }
 
   static loadLocalAndPopulateVideo (rateType: VideoRateType, accountName: string, videoId: number, transaction?: Transaction) {
-    const options: IFindOptions<AccountVideoRateModel> = {
+    const options: FindOptions = {
       where: {
         videoId,
         type: rateType
@@ -155,7 +154,7 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
   }
 
   static loadByUrl (url: string, transaction: Transaction) {
-    const options: IFindOptions<AccountVideoRateModel> = {
+    const options: FindOptions = {
       where: {
         url
       }
index 6f425024e8a5164392032fb647dce67729b6d5d2..bf2ed0a61efb42e0eec138e0565b78a82e959411 100644 (file)
@@ -1,4 +1,3 @@
-import * as Sequelize from 'sequelize'
 import {
   AllowNull,
   BeforeDestroy,
@@ -28,6 +27,7 @@ import { UserModel } from './user'
 import { AvatarModel } from '../avatar/avatar'
 import { VideoPlaylistModel } from '../video/video-playlist'
 import { WEBSERVER } from '../../initializers/constants'
+import { Op, Transaction, WhereOptions } from 'sequelize'
 
 export enum ScopeNames {
   SUMMARY = 'SUMMARY'
@@ -42,7 +42,7 @@ export enum ScopeNames {
   ]
 })
 @Scopes({
-  [ ScopeNames.SUMMARY ]: (whereActor?: Sequelize.WhereOptions<ActorModel>) => {
+  [ ScopeNames.SUMMARY ]: (whereActor?: WhereOptions) => {
     return {
       attributes: [ 'id', 'name' ],
       include: [
@@ -90,7 +90,7 @@ export class AccountModel extends Model<AccountModel> {
 
   @AllowNull(true)
   @Default(null)
-  @Is('AccountDescription', value => throwIfNotValid(value, isAccountDescriptionValid, 'description'))
+  @Is('AccountDescription', value => throwIfNotValid(value, isAccountDescriptionValid, 'description', true))
   @Column
   description: string
 
@@ -176,7 +176,7 @@ export class AccountModel extends Model<AccountModel> {
     return undefined
   }
 
-  static load (id: number, transaction?: Sequelize.Transaction) {
+  static load (id: number, transaction?: Transaction) {
     return AccountModel.findByPk(id, { transaction })
   }
 
@@ -207,15 +207,15 @@ export class AccountModel extends Model<AccountModel> {
   static loadLocalByName (name: string) {
     const query = {
       where: {
-        [ Sequelize.Op.or ]: [
+        [ Op.or ]: [
           {
             userId: {
-              [ Sequelize.Op.ne ]: null
+              [ Op.ne ]: null
             }
           },
           {
             applicationId: {
-              [ Sequelize.Op.ne ]: null
+              [ Op.ne ]: null
             }
           }
         ]
@@ -259,7 +259,7 @@ export class AccountModel extends Model<AccountModel> {
     return AccountModel.findOne(query)
   }
 
-  static loadByUrl (url: string, transaction?: Sequelize.Transaction) {
+  static loadByUrl (url: string, transaction?: Transaction) {
     const query = {
       include: [
         {
index 33480f3b585b205be6040623bcd3bb8dd7386aab..08388f2687e7aa537144c7fd39c7a65da161bdc5 100644 (file)
@@ -1,17 +1,4 @@
-import {
-  AllowNull,
-  BelongsTo,
-  Column,
-  CreatedAt,
-  Default,
-  ForeignKey,
-  IFindOptions,
-  Is,
-  Model,
-  Scopes,
-  Table,
-  UpdatedAt
-} from 'sequelize-typescript'
+import { AllowNull, BelongsTo, Column, CreatedAt, Default, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
 import { UserNotification, UserNotificationType } from '../../../shared'
 import { getSort, throwIfNotValid } from '../utils'
 import { isBooleanValid } from '../../helpers/custom-validators/misc'
@@ -19,7 +6,7 @@ import { isUserNotificationTypeValid } from '../../helpers/custom-validators/use
 import { UserModel } from './user'
 import { VideoModel } from '../video/video'
 import { VideoCommentModel } from '../video/video-comment'
-import { Op } from 'sequelize'
+import { FindOptions, Op } from 'sequelize'
 import { VideoChannelModel } from '../video/video-channel'
 import { AccountModel } from './account'
 import { VideoAbuseModel } from '../video/video-abuse'
@@ -160,7 +147,7 @@ function buildAccountInclude (required: boolean, withActor = false) {
       },
 
       buildAccountInclude(false, true)
-    ]
+    ] as any // FIXME: sequelize typings
   }
 })
 @Table({
@@ -225,7 +212,7 @@ function buildAccountInclude (required: boolean, withActor = false) {
         }
       }
     }
-  ]
+  ] as any // FIXME: sequelize typings
 })
 export class UserNotificationModel extends Model<UserNotificationModel> {
 
@@ -344,7 +331,7 @@ export class UserNotificationModel extends Model<UserNotificationModel> {
   ActorFollow: ActorFollowModel
 
   static listForApi (userId: number, start: number, count: number, sort: string, unread?: boolean) {
-    const query: IFindOptions<UserNotificationModel> = {
+    const query: FindOptions = {
       offset: start,
       limit: count,
       order: getSort(sort),
index 49d2def8158386a64aa17c2b1b07cbdce2f78253..a862fc45fb859b0d842877c888b76233aec0962a 100644 (file)
@@ -76,7 +76,7 @@ export class UserVideoHistoryModel extends Model<UserVideoHistoryModel> {
     }
 
     if (beforeDate) {
-      query.where.updatedAt = {
+      query.where['updatedAt'] = {
         [Op.lt]: beforeDate
       }
     }
index b66458351a6eb6dc0871947c5ac4da1ebad20b78..8bd0397dd50e5a776510a83344a9d42593710b19 100644 (file)
@@ -80,7 +80,7 @@ enum ScopeNames {
         model: () => UserNotificationSettingModel,
         required: true
       }
-    ]
+    ] as any // FIXME: sequelize typings
   }
 })
 @Table({
@@ -115,13 +115,13 @@ export class UserModel extends Model<UserModel> {
 
   @AllowNull(true)
   @Default(null)
-  @Is('UserEmailVerified', value => throwIfNotValid(value, isUserEmailVerifiedValid, 'email verified boolean'))
+  @Is('UserEmailVerified', value => throwIfNotValid(value, isUserEmailVerifiedValid, 'email verified boolean', true))
   @Column
   emailVerified: boolean
 
   @AllowNull(false)
   @Is('UserNSFWPolicy', value => throwIfNotValid(value, isUserNSFWPolicyValid, 'NSFW policy'))
-  @Column(DataType.ENUM(values(NSFW_POLICY_TYPES)))
+  @Column(DataType.ENUM(...values(NSFW_POLICY_TYPES)))
   nsfwPolicy: NSFWPolicyType
 
   @AllowNull(false)
@@ -156,7 +156,7 @@ export class UserModel extends Model<UserModel> {
 
   @AllowNull(true)
   @Default(null)
-  @Is('UserBlockedReason', value => throwIfNotValid(value, isUserBlockedReasonValid, 'blocked reason'))
+  @Is('UserBlockedReason', value => throwIfNotValid(value, isUserBlockedReasonValid, 'blocked reason', true))
   @Column
   blockedReason: string
 
@@ -556,10 +556,10 @@ export class UserModel extends Model<UserModel> {
       notificationSettings: this.NotificationSetting ? this.NotificationSetting.toFormattedJSON() : undefined,
       videoChannels: [],
       videoQuotaUsed: videoQuotaUsed !== undefined
-            ? parseInt(videoQuotaUsed, 10)
+            ? parseInt(videoQuotaUsed + '', 10)
             : undefined,
       videoQuotaUsedDaily: videoQuotaUsedDaily !== undefined
-            ? parseInt(videoQuotaUsedDaily, 10)
+            ? parseInt(videoQuotaUsedDaily + '', 10)
             : undefined
     }
 
@@ -619,14 +619,14 @@ export class UserModel extends Model<UserModel> {
   private static getTotalRawQuery (query: string, userId: number) {
     const options = {
       bind: { userId },
-      type: Sequelize.QueryTypes.SELECT
+      type: Sequelize.QueryTypes.SELECT as Sequelize.QueryTypes.SELECT
     }
 
-    return UserModel.sequelize.query(query, options)
+    return UserModel.sequelize.query<{ total: number }>(query, options)
                     .then(([ { total } ]) => {
                       if (total === null) return 0
 
-                      return parseInt(total, 10)
+                      return parseInt(total + '', 10)
                     })
   }
 }
index f9b4f57f3413d9a66d117c971d06c6eae1263f17..b0461b98110f1740eb85a2d11bae9aab4128c494 100644 (file)
@@ -1,6 +1,5 @@
 import * as Bluebird from 'bluebird'
 import { values } from 'lodash'
-import * as Sequelize from 'sequelize'
 import {
   AfterCreate,
   AfterDestroy,
@@ -27,8 +26,8 @@ import { ServerModel } from '../server/server'
 import { getSort } from '../utils'
 import { ActorModel, unusedActorAttributesForAPI } from './actor'
 import { VideoChannelModel } from '../video/video-channel'
-import { IIncludeOptions } from '../../../node_modules/sequelize-typescript/lib/interfaces/IIncludeOptions'
 import { AccountModel } from '../account/account'
+import { IncludeOptions, Op, Transaction, QueryTypes } from 'sequelize'
 
 @Table({
   tableName: 'actorFollow',
@@ -51,7 +50,7 @@ import { AccountModel } from '../account/account'
 export class ActorFollowModel extends Model<ActorFollowModel> {
 
   @AllowNull(false)
-  @Column(DataType.ENUM(values(FOLLOW_STATES)))
+  @Column(DataType.ENUM(...values(FOLLOW_STATES)))
   state: FollowState
 
   @AllowNull(false)
@@ -126,7 +125,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
     if (numberOfActorFollowsRemoved) logger.info('Removed bad %d actor follows.', numberOfActorFollowsRemoved)
   }
 
-  static loadByActorAndTarget (actorId: number, targetActorId: number, t?: Sequelize.Transaction) {
+  static loadByActorAndTarget (actorId: number, targetActorId: number, t?: Transaction) {
     const query = {
       where: {
         actorId,
@@ -150,8 +149,8 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
     return ActorFollowModel.findOne(query)
   }
 
-  static loadByActorAndTargetNameAndHostForAPI (actorId: number, targetName: string, targetHost: string, t?: Sequelize.Transaction) {
-    const actorFollowingPartInclude: IIncludeOptions = {
+  static loadByActorAndTargetNameAndHostForAPI (actorId: number, targetName: string, targetHost: string, t?: Transaction) {
+    const actorFollowingPartInclude: IncludeOptions = {
       model: ActorModel,
       required: true,
       as: 'ActorFollowing',
@@ -208,7 +207,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
       .map(t => {
         if (t.host) {
           return {
-            [ Sequelize.Op.and ]: [
+            [ Op.and ]: [
               {
                 '$preferredUsername$': t.name
               },
@@ -220,7 +219,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
         }
 
         return {
-          [ Sequelize.Op.and ]: [
+          [ Op.and ]: [
             {
               '$preferredUsername$': t.name
             },
@@ -234,9 +233,9 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
     const query = {
       attributes: [],
       where: {
-        [ Sequelize.Op.and ]: [
+        [ Op.and ]: [
           {
-            [ Sequelize.Op.or ]: whereTab
+            [ Op.or ]: whereTab
           },
           {
             actorId
@@ -288,7 +287,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
               required: true,
               where: search ? {
                 host: {
-                  [Sequelize.Op.iLike]: '%' + search + '%'
+                  [Op.iLike]: '%' + search + '%'
                 }
               } : undefined
             }
@@ -323,7 +322,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
               required: true,
               where: search ? {
                 host: {
-                  [ Sequelize.Op.iLike ]: '%' + search + '%'
+                  [ Op.iLike ]: '%' + search + '%'
                 }
               } : undefined
             }
@@ -406,11 +405,11 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
                            })
   }
 
-  static listAcceptedFollowerUrlsForAP (actorIds: number[], t: Sequelize.Transaction, start?: number, count?: number) {
+  static listAcceptedFollowerUrlsForAP (actorIds: number[], t: Transaction, start?: number, count?: number) {
     return ActorFollowModel.createListAcceptedFollowForApiQuery('followers', actorIds, t, start, count)
   }
 
-  static listAcceptedFollowerSharedInboxUrls (actorIds: number[], t: Sequelize.Transaction) {
+  static listAcceptedFollowerSharedInboxUrls (actorIds: number[], t: Transaction) {
     return ActorFollowModel.createListAcceptedFollowForApiQuery(
       'followers',
       actorIds,
@@ -422,7 +421,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
     )
   }
 
-  static listAcceptedFollowingUrlsForApi (actorIds: number[], t: Sequelize.Transaction, start?: number, count?: number) {
+  static listAcceptedFollowingUrlsForApi (actorIds: number[], t: Transaction, start?: number, count?: number) {
     return ActorFollowModel.createListAcceptedFollowForApiQuery('following', actorIds, t, start, count)
   }
 
@@ -447,7 +446,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
     }
   }
 
-  static updateFollowScore (inboxUrl: string, value: number, t?: Sequelize.Transaction) {
+  static updateFollowScore (inboxUrl: string, value: number, t?: Transaction) {
     const query = `UPDATE "actorFollow" SET "score" = LEAST("score" + ${value}, ${ACTOR_FOLLOW_SCORE.MAX}) ` +
       'WHERE id IN (' +
         'SELECT "actorFollow"."id" FROM "actorFollow" ' +
@@ -456,7 +455,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
       ')'
 
     const options = {
-      type: Sequelize.QueryTypes.BULKUPDATE,
+      type: QueryTypes.BULKUPDATE,
       transaction: t
     }
 
@@ -466,7 +465,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
   private static async createListAcceptedFollowForApiQuery (
     type: 'followers' | 'following',
     actorIds: number[],
-    t: Sequelize.Transaction,
+    t: Transaction,
     start?: number,
     count?: number,
     columnUrl = 'url',
@@ -502,7 +501,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
 
       const options = {
         bind: { actorIds },
-        type: Sequelize.QueryTypes.SELECT,
+        type: QueryTypes.SELECT,
         transaction: t
       }
       tasks.push(ActorFollowModel.sequelize.query(query, options))
@@ -521,7 +520,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
     const query = {
       where: {
         score: {
-          [Sequelize.Op.lte]: 0
+          [Op.lte]: 0
         }
       },
       logging: false
index e8f603031de35838e1eb7c51e25cc309b24ba526..1ebee8df514c31abfd2be2669022ab37ff26fdcc 100644 (file)
@@ -93,7 +93,7 @@ export const unusedActorAttributesForAPI = [
         model: () => AvatarModel,
         required: false
       }
-    ]
+    ] as any // FIXME: sequelize typings
   }
 })
 @Table({
@@ -131,7 +131,7 @@ export const unusedActorAttributesForAPI = [
 export class ActorModel extends Model<ActorModel> {
 
   @AllowNull(false)
-  @Column(DataType.ENUM(values(ACTIVITY_PUB_ACTOR_TYPES)))
+  @Column({ type: DataType.ENUM(...values(ACTIVITY_PUB_ACTOR_TYPES)) }) // FIXME: sequelize typings
   type: ActivityPubActorType
 
   @AllowNull(false)
@@ -151,12 +151,12 @@ export class ActorModel extends Model<ActorModel> {
   url: string
 
   @AllowNull(true)
-  @Is('ActorPublicKey', value => throwIfNotValid(value, isActorPublicKeyValid, 'public key'))
+  @Is('ActorPublicKey', value => throwIfNotValid(value, isActorPublicKeyValid, 'public key', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTORS.PUBLIC_KEY.max))
   publicKey: string
 
   @AllowNull(true)
-  @Is('ActorPublicKey', value => throwIfNotValid(value, isActorPrivateKeyValid, 'private key'))
+  @Is('ActorPublicKey', value => throwIfNotValid(value, isActorPrivateKeyValid, 'private key', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.ACTORS.PRIVATE_KEY.max))
   privateKey: string
 
index 24badb166840a9a89673827af501994e6a9b876f..6c11332a1acb187eee577631e697528cb6de7a61 100644 (file)
@@ -1,24 +1,24 @@
-import * as Sequelize from 'sequelize'
+import { ModelAttributeColumnOptions } from 'sequelize'
 
 declare namespace Migration {
-  interface Boolean extends Sequelize.DefineAttributeColumnOptions {
+  interface Boolean extends ModelAttributeColumnOptions {
     defaultValue: boolean | null
   }
 
-  interface String extends Sequelize.DefineAttributeColumnOptions {
+  interface String extends ModelAttributeColumnOptions {
     defaultValue: string | null
   }
 
-  interface Integer extends Sequelize.DefineAttributeColumnOptions {
+  interface Integer extends ModelAttributeColumnOptions {
     defaultValue: number | null
   }
 
-  interface BigInteger extends Sequelize.DefineAttributeColumnOptions {
-    defaultValue: Sequelize.DataTypeBigInt | number | null
+  interface BigInteger extends ModelAttributeColumnOptions {
+    defaultValue: number | null
   }
 
-  interface UUID extends Sequelize.DefineAttributeColumnOptions {
-    defaultValue: Sequelize.DataTypeUUIDv4 | null
+  interface UUID extends ModelAttributeColumnOptions {
+    defaultValue: null
   }
 }
 
index 42c59bb7923431c263f44e947c3519509b9365d3..b4a841edd82386db4b7328f59c68958d21f0865c 100644 (file)
@@ -24,10 +24,10 @@ export class OAuthClientModel extends Model<OAuthClientModel> {
   @Column
   clientSecret: string
 
-  @Column(DataType.ARRAY(DataType.STRING))
+  @Column({ type: DataType.ARRAY(DataType.STRING) }) // FIXME: sequelize typings
   grants: string[]
 
-  @Column(DataType.ARRAY(DataType.STRING))
+  @Column({ type: DataType.ARRAY(DataType.STRING) }) // FIXME: sequelize typings
   redirectUris: string[]
 
   @CreatedAt
index 08d892da43b2ea59cd60c7cd8735ad2c9282302a..3f41ee63be6c0a51b97a4bc0f9ec3f6533b1586b 100644 (file)
@@ -55,7 +55,7 @@ enum ScopeNames {
           }
         ]
       }
-    ]
+    ] as any // FIXME: sequelize typings
   }
 })
 @Table({
index 2b8e44223e40a0e183a8896a10eb2594f9e1da2e..cbeaa662b52710917fc6458851b9d16bff4a358b 100644 (file)
@@ -58,7 +58,7 @@ export enum ScopeNames {
           }
         ]
       }
-    ]
+    ] as any // FIXME: sequelize typings
   }
 })
 
index a478bc62b43381757bd841908ca163e87cb38ee7..98170a00e14ec2c7275e8992b9874d3c2f3e1b09 100644 (file)
@@ -1,26 +1,29 @@
 import { Sequelize } from 'sequelize-typescript'
 import * as validator from 'validator'
+import { OrderItem } from 'sequelize'
+import { Col } from 'sequelize/types/lib/utils'
 
 type SortType = { sortModel: any, sortValue: string }
 
 // Translate for example "-name" to [ [ 'name', 'DESC' ], [ 'id', 'ASC' ] ]
-function getSort (value: string, lastSort: string[] = [ 'id', 'ASC' ]) {
-  let { direction, field } = buildDirectionAndField(value)
+function getSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
+  const { direction, field } = buildDirectionAndField(value)
+
+  let finalField: string | Col
 
   if (field.toLowerCase() === 'match') { // Search
-    field = Sequelize.col('similarity')
+    finalField = Sequelize.col('similarity')
+  } else {
+    finalField = field
   }
 
-  return [ [ field, direction ], lastSort ]
+  return [ [ finalField, direction ], lastSort ]
 }
 
-function getVideoSort (value: string, lastSort: string[] = [ 'id', 'ASC' ]) {
-  let { direction, field } = buildDirectionAndField(value)
+function getVideoSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
+  const { direction, field } = buildDirectionAndField(value)
 
-  // Alias
-  if (field.toLowerCase() === 'match') { // Search
-    field = Sequelize.col('similarity')
-  } else if (field.toLowerCase() === 'trending') { // Sort by aggregation
+  if (field.toLowerCase() === 'trending') { // Sort by aggregation
     return [
       [ Sequelize.fn('COALESCE', Sequelize.fn('SUM', Sequelize.col('VideoViews.views')), '0'), direction ],
 
@@ -30,15 +33,24 @@ function getVideoSort (value: string, lastSort: string[] = [ 'id', 'ASC' ]) {
     ]
   }
 
-  const firstSort = typeof field === 'string' ?
-    field.split('.').concat([ direction ]) :
-    [ field, direction ]
+  let finalField: string | Col
+
+  // Alias
+  if (field.toLowerCase() === 'match') { // Search
+    finalField = Sequelize.col('similarity')
+  } else {
+    finalField = field
+  }
+
+  const firstSort = typeof finalField === 'string'
+    ? finalField.split('.').concat([ direction ]) as any // FIXME: sequelize typings
+    : [ finalField, direction ]
 
   return [ firstSort, lastSort ]
 }
 
-function getSortOnModel (model: any, value: string, lastSort: string[] = [ 'id', 'ASC' ]) {
-  let [ firstSort ] = getSort(value)
+function getSortOnModel (model: any, value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
+  const [ firstSort ] = getSort(value)
 
   if (model) return [ [ model, firstSort[0], firstSort[1] ], lastSort ]
   return [ firstSort, lastSort ]
@@ -52,7 +64,9 @@ function isOutdated (model: { createdAt: Date, updatedAt: Date }, refreshInterva
   return (now - createdAtTime) > refreshInterval && (now - updatedAtTime) > refreshInterval
 }
 
-function throwIfNotValid (value: any, validator: (value: any) => boolean, fieldName = 'value') {
+function throwIfNotValid (value: any, validator: (value: any) => boolean, fieldName = 'value', nullable = false) {
+  if (nullable && (value === null || value === undefined)) return
+
   if (validator(value) === false) {
     throw new Error(`"${value}" is not a valid ${fieldName}.`)
   }
@@ -131,7 +145,7 @@ function searchTrigramNormalizeCol (col: string) {
 }
 
 function buildDirectionAndField (value: string) {
-  let field: any
+  let field: string
   let direction: 'ASC' | 'DESC'
 
   if (value.substring(0, 1) === '-') {
index abddc111144008684c655ee51523b41c8d223562..b9e9ed9a08692ce87161ea2cb103b3853fafeb06 100644 (file)
@@ -1,7 +1,7 @@
-import { AllowNull, BelongsTo, Column, CreatedAt, Default, ForeignKey, Model, Sequelize, Table, UpdatedAt } from 'sequelize-typescript'
+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 { Transaction } from 'sequelize'
+import { Op, Transaction } from 'sequelize'
 
 @Table({
   tableName: 'scheduleVideoUpdate',
@@ -51,7 +51,7 @@ export class ScheduleVideoUpdateModel extends Model<ScheduleVideoUpdateModel> {
       attributes: [ 'id' ],
       where: {
         updateAt: {
-          [Sequelize.Op.lte]: new Date()
+          [Op.lte]: new Date()
         }
       }
     }
@@ -64,7 +64,7 @@ export class ScheduleVideoUpdateModel extends Model<ScheduleVideoUpdateModel> {
     const query = {
       where: {
         updateAt: {
-          [Sequelize.Op.lte]: new Date()
+          [Op.lte]: new Date()
         }
       },
       include: [
index b39621eaf4a4daf55cdb93a3a5f0fe903674bd7f..048b4761368d7451d2055a7531c86161dd797e2e 100644 (file)
@@ -1,5 +1,5 @@
 import * as Bluebird from 'bluebird'
-import * as Sequelize from 'sequelize'
+import { QueryTypes, Transaction } from 'sequelize'
 import { AllowNull, BelongsToMany, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
 import { isVideoTagValid } from '../../helpers/custom-validators/videos'
 import { throwIfNotValid } from '../utils'
@@ -37,7 +37,7 @@ export class TagModel extends Model<TagModel> {
   })
   Videos: VideoModel[]
 
-  static findOrCreateTags (tags: string[], transaction: Sequelize.Transaction) {
+  static findOrCreateTags (tags: string[], transaction: Transaction) {
     if (tags === null) return []
 
     const tasks: Bluebird<TagModel>[] = []
@@ -72,10 +72,10 @@ export class TagModel extends Model<TagModel> {
 
     const options = {
       bind: { threshold, count, videoPrivacy: VideoPrivacy.PUBLIC, videoState: VideoState.PUBLISHED },
-      type: Sequelize.QueryTypes.SELECT
+      type: QueryTypes.SELECT as QueryTypes.SELECT
     }
 
-    return TagModel.sequelize.query(query, options)
+    return TagModel.sequelize.query<{ name }>(query, options)
                     .then(data => data.map(d => d.name))
   }
 }
index eacd651cc1233dd4679d74cd0349a0f905b6aed3..1ac7919b31e2c70f8d06c08a6ffd881e205565c8 100644 (file)
@@ -39,7 +39,7 @@ export class VideoAbuseModel extends Model<VideoAbuseModel> {
 
   @AllowNull(true)
   @Default(null)
-  @Is('VideoAbuseModerationComment', value => throwIfNotValid(value, isVideoAbuseModerationCommentValid, 'moderationComment'))
+  @Is('VideoAbuseModerationComment', value => throwIfNotValid(value, isVideoAbuseModerationCommentValid, 'moderationComment', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.MODERATION_COMMENT.max))
   moderationComment: string
 
index 2619b49500c086c0a28f7299cd1f7964a39d2e3f..d9fe9dfc964ed9dc861aa132e8a7a74d3371cbb0 100644 (file)
@@ -1,22 +1,11 @@
-import {
-  AllowNull,
-  BelongsTo,
-  Column,
-  CreatedAt,
-  DataType,
-  Default,
-  ForeignKey,
-  Is, Model,
-  Table,
-  UpdatedAt,
-  IFindOptions
-} from 'sequelize-typescript'
+import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
 import { getSortOnModel, SortType, throwIfNotValid } from '../utils'
 import { VideoModel } from './video'
-import { VideoChannelModel, ScopeNames as VideoChannelScopeNames } from './video-channel'
+import { ScopeNames as VideoChannelScopeNames, VideoChannelModel } from './video-channel'
 import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist'
 import { VideoBlacklist, VideoBlacklistType } from '../../../shared/models/videos'
 import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
+import { FindOptions } from 'sequelize'
 
 @Table({
   tableName: 'videoBlacklist',
@@ -30,7 +19,7 @@ import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
 export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
 
   @AllowNull(true)
-  @Is('VideoBlacklistReason', value => throwIfNotValid(value, isVideoBlacklistReasonValid, 'reason'))
+  @Is('VideoBlacklistReason', value => throwIfNotValid(value, isVideoBlacklistReasonValid, 'reason', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_BLACKLIST.REASON.max))
   reason: string
 
@@ -63,7 +52,7 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
   Video: VideoModel
 
   static listForApi (start: number, count: number, sort: SortType, type?: VideoBlacklistType) {
-    const query: IFindOptions<VideoBlacklistModel> = {
+    const query: FindOptions = {
       offset: start,
       limit: count,
       order: getSortOnModel(sort.sortModel, sort.sortValue),
index f2dbbfde82821570aa443bc67d5711e4ec66839f..45c60e26bbe7c5699f5fd6609045095da4cb82ef 100644 (file)
@@ -1,4 +1,4 @@
-import * as Sequelize from 'sequelize'
+import { OrderItem, Transaction } from 'sequelize'
 import {
   AllowNull,
   BeforeDestroy,
@@ -115,19 +115,19 @@ export class VideoCaptionModel extends Model<VideoCaptionModel> {
     return VideoCaptionModel.findOne(query)
   }
 
-  static insertOrReplaceLanguage (videoId: number, language: string, transaction: Sequelize.Transaction) {
+  static insertOrReplaceLanguage (videoId: number, language: string, transaction: Transaction) {
     const values = {
       videoId,
       language
     }
 
-    return VideoCaptionModel.upsert<VideoCaptionModel>(values, { transaction, returning: true })
+    return (VideoCaptionModel.upsert<VideoCaptionModel>(values, { transaction, returning: true }) as any) // FIXME: typings
       .then(([ caption ]) => caption)
   }
 
   static listVideoCaptions (videoId: number) {
     const query = {
-      order: [ [ 'language', 'ASC' ] ],
+      order: [ [ 'language', 'ASC' ] ] as OrderItem[],
       where: {
         videoId
       }
@@ -140,7 +140,7 @@ export class VideoCaptionModel extends Model<VideoCaptionModel> {
     return VIDEO_LANGUAGES[language] || 'Unknown'
   }
 
-  static deleteAllCaptionsOfRemoteVideo (videoId: number, transaction: Sequelize.Transaction) {
+  static deleteAllCaptionsOfRemoteVideo (videoId: number, transaction: Transaction) {
     const query = {
       where: {
         videoId
index 85e688c4f3abd1a05ac48be114ad77d77ef83716..a4f4d53f1b00368ae2b84f6a30dc8bbf539e959a 100644 (file)
@@ -43,7 +43,7 @@ enum ScopeNames {
           { model: () => VideoFileModel }
         ]
       }
-    ]
+    ] as any // FIXME: sequelize typings
   }
 })
 export class VideoChangeOwnershipModel extends Model<VideoChangeOwnershipModel> {
index 5b50753445647923728d06df81c3f54c2bbb7b23..901006deae1a13c63831c8f847adfdd54bc00263 100644 (file)
@@ -9,7 +9,6 @@ import {
   DefaultScope,
   ForeignKey,
   HasMany,
-  IFindOptions,
   Is,
   Model,
   Scopes,
@@ -31,12 +30,12 @@ import { buildServerIdsFollowedBy, buildTrigramSearchIndex, createSimilarityAttr
 import { VideoModel } from './video'
 import { CONSTRAINTS_FIELDS, WEBSERVER } from '../../initializers/constants'
 import { ServerModel } from '../server/server'
-import { DefineIndexesOptions } from 'sequelize'
+import { FindOptions, ModelIndexesOptions, Op } from 'sequelize'
 import { AvatarModel } from '../avatar/avatar'
 import { VideoPlaylistModel } from './video-playlist'
 
 // FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
-const indexes: DefineIndexesOptions[] = [
+const indexes: ModelIndexesOptions[] = [
   buildTrigramSearchIndex('video_channel_name_trigram', 'name'),
 
   {
@@ -69,7 +68,7 @@ type AvailableForListOptions = {
 })
 @Scopes({
   [ScopeNames.SUMMARY]: (withAccount = false) => {
-    const base: IFindOptions<VideoChannelModel> = {
+    const base: FindOptions = {
       attributes: [ 'name', 'description', 'id', 'actorId' ],
       include: [
         {
@@ -112,13 +111,13 @@ type AvailableForListOptions = {
           },
           model: ActorModel,
           where: {
-            [Sequelize.Op.or]: [
+            [Op.or]: [
               {
                 serverId: null
               },
               {
                 serverId: {
-                  [ Sequelize.Op.in ]: Sequelize.literal(inQueryInstanceFollow)
+                  [ Op.in ]: Sequelize.literal(inQueryInstanceFollow)
                 }
               }
             ]
@@ -172,13 +171,13 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
 
   @AllowNull(true)
   @Default(null)
-  @Is('VideoChannelDescription', value => throwIfNotValid(value, isVideoChannelDescriptionValid, 'description'))
+  @Is('VideoChannelDescription', value => throwIfNotValid(value, isVideoChannelDescriptionValid, 'description', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_CHANNELS.DESCRIPTION.max))
   description: string
 
   @AllowNull(true)
   @Default(null)
-  @Is('VideoChannelSupport', value => throwIfNotValid(value, isVideoChannelSupportValid, 'support'))
+  @Is('VideoChannelSupport', value => throwIfNotValid(value, isVideoChannelSupportValid, 'support', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_CHANNELS.SUPPORT.max))
   support: string
 
@@ -313,7 +312,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
       limit: options.count,
       order: getSort(options.sort),
       where: {
-        [Sequelize.Op.or]: [
+        [Op.or]: [
           Sequelize.literal(
             'lower(immutable_unaccent("VideoChannelModel"."name")) % lower(immutable_unaccent(' + escapedSearch + '))'
           ),
index cb5f1cbbe067d2d73d22d4cb28205eed3c6c83d5..5f7cd36710d055e66bb6e18c6d064e2f85b50f86 100644 (file)
@@ -1,4 +1,3 @@
-import * as Sequelize from 'sequelize'
 import {
   AllowNull,
   BeforeDestroy,
@@ -7,7 +6,6 @@ import {
   CreatedAt,
   DataType,
   ForeignKey,
-  IFindOptions,
   Is,
   Model,
   Scopes,
@@ -32,6 +30,7 @@ import { UserModel } from '../account/user'
 import { actorNameAlphabet } from '../../helpers/custom-validators/activitypub/actor'
 import { regexpCapture } from '../../helpers/regexp'
 import { uniq } from 'lodash'
+import { FindOptions, Op, Order, Sequelize, Transaction } from 'sequelize'
 
 enum ScopeNames {
   WITH_ACCOUNT = 'WITH_ACCOUNT',
@@ -86,7 +85,7 @@ enum ScopeNames {
           }
         ]
       }
-    ]
+    ] as any // FIXME: sequelize typings
   },
   [ScopeNames.WITH_IN_REPLY_TO]: {
     include: [
@@ -120,7 +119,7 @@ enum ScopeNames {
           }
         ]
       }
-    ]
+    ] as any // FIXME: sequelize typings
   }
 })
 @Table({
@@ -244,8 +243,8 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
     }
   }
 
-  static loadById (id: number, t?: Sequelize.Transaction) {
-    const query: IFindOptions<VideoCommentModel> = {
+  static loadById (id: number, t?: Transaction) {
+    const query: FindOptions = {
       where: {
         id
       }
@@ -256,8 +255,8 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
     return VideoCommentModel.findOne(query)
   }
 
-  static loadByIdAndPopulateVideoAndAccountAndReply (id: number, t?: Sequelize.Transaction) {
-    const query: IFindOptions<VideoCommentModel> = {
+  static loadByIdAndPopulateVideoAndAccountAndReply (id: number, t?: Transaction) {
+    const query: FindOptions = {
       where: {
         id
       }
@@ -270,8 +269,8 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
       .findOne(query)
   }
 
-  static loadByUrlAndPopulateAccount (url: string, t?: Sequelize.Transaction) {
-    const query: IFindOptions<VideoCommentModel> = {
+  static loadByUrlAndPopulateAccount (url: string, t?: Transaction) {
+    const query: FindOptions = {
       where: {
         url
       }
@@ -282,8 +281,8 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
     return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT ]).findOne(query)
   }
 
-  static loadByUrlAndPopulateReplyAndVideo (url: string, t?: Sequelize.Transaction) {
-    const query: IFindOptions<VideoCommentModel> = {
+  static loadByUrlAndPopulateReplyAndVideo (url: string, t?: Transaction) {
+    const query: FindOptions = {
       where: {
         url
       }
@@ -307,7 +306,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
         videoId,
         inReplyToCommentId: null,
         accountId: {
-          [Sequelize.Op.notIn]: Sequelize.literal(
+          [Op.notIn]: Sequelize.literal(
             '(' + buildBlockedAccountSQL(serverAccountId, userAccountId) + ')'
           )
         }
@@ -336,15 +335,15 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
     const userAccountId = user ? user.Account.id : undefined
 
     const query = {
-      order: [ [ 'createdAt', 'ASC' ], [ 'updatedAt', 'ASC' ] ],
+      order: [ [ 'createdAt', 'ASC' ], [ 'updatedAt', 'ASC' ] ] as Order,
       where: {
         videoId,
-        [ Sequelize.Op.or ]: [
+        [ Op.or ]: [
           { id: threadId },
           { originCommentId: threadId }
         ],
         accountId: {
-          [Sequelize.Op.notIn]: Sequelize.literal(
+          [Op.notIn]: Sequelize.literal(
             '(' + buildBlockedAccountSQL(serverAccountId, userAccountId) + ')'
           )
         }
@@ -366,12 +365,12 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
       })
   }
 
-  static listThreadParentComments (comment: VideoCommentModel, t: Sequelize.Transaction, order: 'ASC' | 'DESC' = 'ASC') {
+  static listThreadParentComments (comment: VideoCommentModel, t: Transaction, order: 'ASC' | 'DESC' = 'ASC') {
     const query = {
-      order: [ [ 'createdAt', order ] ],
+      order: [ [ 'createdAt', order ] ] as Order,
       where: {
         id: {
-          [ Sequelize.Op.in ]: Sequelize.literal('(' +
+          [ Op.in ]: Sequelize.literal('(' +
             'WITH RECURSIVE children (id, "inReplyToCommentId") AS ( ' +
               `SELECT id, "inReplyToCommentId" FROM "videoComment" WHERE id = ${comment.id} ` +
               'UNION ' +
@@ -380,7 +379,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
             ') ' +
             'SELECT id FROM children' +
           ')'),
-          [ Sequelize.Op.ne ]: comment.id
+          [ Op.ne ]: comment.id
         }
       },
       transaction: t
@@ -391,9 +390,9 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
       .findAll(query)
   }
 
-  static listAndCountByVideoId (videoId: number, start: number, count: number, t?: Sequelize.Transaction, order: 'ASC' | 'DESC' = 'ASC') {
+  static listAndCountByVideoId (videoId: number, start: number, count: number, t?: Transaction, order: 'ASC' | 'DESC' = 'ASC') {
     const query = {
-      order: [ [ 'createdAt', order ] ],
+      order: [ [ 'createdAt', order ] ] as Order,
       offset: start,
       limit: count,
       where: {
@@ -407,7 +406,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
 
   static listForFeed (start: number, count: number, videoId?: number) {
     const query = {
-      order: [ [ 'createdAt', 'DESC' ] ],
+      order: [ [ 'createdAt', 'DESC' ] ] as Order,
       offset: start,
       limit: count,
       where: {},
@@ -457,7 +456,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
     const query = {
       where: {
         updatedAt: {
-          [Sequelize.Op.lt]: beforeUpdatedAt
+          [Op.lt]: beforeUpdatedAt
         },
         videoId
       }
index ec10085d644db923579fef6837896ce6afa1a050..588a13a4fb71a27cbe8859224f8732cf0298a36f 100644 (file)
@@ -55,13 +55,13 @@ export class VideoImportModel extends Model<VideoImportModel> {
 
   @AllowNull(true)
   @Default(null)
-  @Is('VideoImportTargetUrl', value => throwIfNotValid(value, isVideoImportTargetUrlValid, 'targetUrl'))
+  @Is('VideoImportTargetUrl', value => throwIfNotValid(value, isVideoImportTargetUrlValid, 'targetUrl', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_IMPORTS.URL.max))
   targetUrl: string
 
   @AllowNull(true)
   @Default(null)
-  @Is('VideoImportMagnetUri', value => throwIfNotValid(value, isVideoMagnetUriValid, 'magnetUri'))
+  @Is('VideoImportMagnetUri', value => throwIfNotValid(value, isVideoMagnetUriValid, 'magnetUri', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_IMPORTS.URL.max)) // Use the same constraints than URLs
   magnetUri: string
 
index 3396b11367902557073a87ef4f36698388836fbf..eeb3d6bbd5ec10059be86a45e5cf4b9e881b0cd4 100644 (file)
@@ -15,12 +15,12 @@ import {
 } from 'sequelize-typescript'
 import { VideoModel } from './video'
 import { VideoPlaylistModel } from './video-playlist'
-import * as Sequelize from 'sequelize'
 import { getSort, throwIfNotValid } from '../utils'
 import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
 import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
 import { PlaylistElementObject } from '../../../shared/models/activitypub/objects/playlist-element-object'
 import * as validator from 'validator'
+import { AggregateOptions, Op, Sequelize, Transaction } from 'sequelize'
 
 @Table({
   tableName: 'videoPlaylistElement',
@@ -96,7 +96,7 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
   })
   Video: VideoModel
 
-  static deleteAllOf (videoPlaylistId: number, transaction?: Sequelize.Transaction) {
+  static deleteAllOf (videoPlaylistId: number, transaction?: Transaction) {
     const query = {
       where: {
         videoPlaylistId
@@ -140,7 +140,7 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
     return VideoPlaylistElementModel.findOne(query)
   }
 
-  static listUrlsOfForAP (videoPlaylistId: number, start: number, count: number, t?: Sequelize.Transaction) {
+  static listUrlsOfForAP (videoPlaylistId: number, start: number, count: number, t?: Transaction) {
     const query = {
       attributes: [ 'url' ],
       offset: start,
@@ -159,8 +159,8 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
       })
   }
 
-  static getNextPositionOf (videoPlaylistId: number, transaction?: Sequelize.Transaction) {
-    const query = {
+  static getNextPositionOf (videoPlaylistId: number, transaction?: Transaction) {
+    const query: AggregateOptions<number> = {
       where: {
         videoPlaylistId
       },
@@ -176,14 +176,14 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
     firstPosition: number,
     endPosition: number,
     newPosition: number,
-    transaction?: Sequelize.Transaction
+    transaction?: Transaction
   ) {
     const query = {
       where: {
         videoPlaylistId,
         position: {
-          [Sequelize.Op.gte]: firstPosition,
-          [Sequelize.Op.lte]: endPosition
+          [Op.gte]: firstPosition,
+          [Op.lte]: endPosition
         }
       },
       transaction,
@@ -198,13 +198,13 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
     fromPosition: number,
     toPosition?: number,
     by = 1,
-    transaction?: Sequelize.Transaction
+    transaction?: Transaction
   ) {
     const query = {
       where: {
         videoPlaylistId,
         position: {
-          [Sequelize.Op.gte]: fromPosition
+          [Op.gte]: fromPosition
         }
       },
       transaction
index 073609c24baaacc7347a6ace6c2fe0aeb54c5364..3e436acfc23a1bee1007a14d44ee3030557ec782 100644 (file)
@@ -15,7 +15,6 @@ import {
   Table,
   UpdatedAt
 } from 'sequelize-typescript'
-import * as Sequelize from 'sequelize'
 import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'
 import { buildServerIdsFollowedBy, buildWhereIdOrUUID, getSort, isOutdated, throwIfNotValid } from '../utils'
 import {
@@ -43,6 +42,7 @@ import { activityPubCollectionPagination } from '../../helpers/activitypub'
 import { VideoPlaylistType } from '../../../shared/models/videos/playlist/video-playlist-type.model'
 import { ThumbnailModel } from './thumbnail'
 import { ActivityIconObject } from '../../../shared/models/activitypub/objects'
+import { fn, literal, Op, Transaction } from 'sequelize'
 
 enum ScopeNames {
   AVAILABLE_FOR_LIST = 'AVAILABLE_FOR_LIST',
@@ -74,7 +74,11 @@ type AvailableForListOptions = {
     attributes: {
       include: [
         [
-          Sequelize.literal('(SELECT COUNT("id") FROM "videoPlaylistElement" WHERE "videoPlaylistId" = "VideoPlaylistModel"."id")'),
+          fn('COUNT', 'toto'),
+          'coucou'
+        ],
+        [
+          literal('(SELECT COUNT("id") FROM "videoPlaylistElement" WHERE "videoPlaylistId" = "VideoPlaylistModel"."id")'),
           'videosLength'
         ]
       ]
@@ -116,13 +120,13 @@ type AvailableForListOptions = {
     // Only list local playlists OR playlists that are on an instance followed by actorId
     const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId)
     const actorWhere = {
-      [ Sequelize.Op.or ]: [
+      [ Op.or ]: [
         {
           serverId: null
         },
         {
           serverId: {
-            [ Sequelize.Op.in ]: Sequelize.literal(inQueryInstanceFollow)
+            [ Op.in ]: literal(inQueryInstanceFollow)
           }
         }
       ]
@@ -155,7 +159,7 @@ type AvailableForListOptions = {
     }
 
     const where = {
-      [Sequelize.Op.and]: whereAnd
+      [Op.and]: whereAnd
     }
 
     const accountScope = {
@@ -206,7 +210,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
   name: string
 
   @AllowNull(true)
-  @Is('VideoPlaylistDescription', value => throwIfNotValid(value, isVideoPlaylistDescriptionValid, 'description'))
+  @Is('VideoPlaylistDescription', value => throwIfNotValid(value, isVideoPlaylistDescriptionValid, 'description', true))
   @Column
   description: string
 
@@ -344,7 +348,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
           model: VideoPlaylistElementModel.unscoped(),
           where: {
             videoId: {
-              [Sequelize.Op.any]: videoIds
+              [Op.any]: videoIds
             }
           },
           required: true
@@ -368,7 +372,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
       .then(e => !!e)
   }
 
-  static loadWithAccountAndChannelSummary (id: number | string, transaction: Sequelize.Transaction) {
+  static loadWithAccountAndChannelSummary (id: number | string, transaction: Transaction) {
     const where = buildWhereIdOrUUID(id)
 
     const query = {
@@ -381,7 +385,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
       .findOne(query)
   }
 
-  static loadWithAccountAndChannel (id: number | string, transaction: Sequelize.Transaction) {
+  static loadWithAccountAndChannel (id: number | string, transaction: Transaction) {
     const where = buildWhereIdOrUUID(id)
 
     const query = {
@@ -412,7 +416,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
     return VIDEO_PLAYLIST_TYPES[type] || 'Unknown'
   }
 
-  static resetPlaylistsOfChannel (videoChannelId: number, transaction: Sequelize.Transaction) {
+  static resetPlaylistsOfChannel (videoChannelId: number, transaction: Transaction) {
     const query = {
       where: {
         videoChannelId
@@ -489,7 +493,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
         label: VideoPlaylistModel.getTypeLabel(this.type)
       },
 
-      videosLength: this.get('videosLength'),
+      videosLength: this.get('videosLength') as number,
 
       createdAt: this.createdAt,
       updatedAt: this.updatedAt,
@@ -499,7 +503,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
     }
   }
 
-  toActivityPubObject (page: number, t: Sequelize.Transaction): Promise<PlaylistObject> {
+  toActivityPubObject (page: number, t: Transaction): Promise<PlaylistObject> {
     const handler = (start: number, count: number) => {
       return VideoPlaylistElementModel.listUrlsOfForAP(this.id, start, count, t)
     }
index e50b5d1068b51a52d8cd2d8b1c6455b1d0fae00b..b30267e0912f0b10eaa9fc51cab7d8739d429d9b 100644 (file)
@@ -1,8 +1,7 @@
-import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, HasMany, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
+import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, HasMany, Is, Model, Table, UpdatedAt, DataType } from 'sequelize-typescript'
 import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos'
 import { throwIfNotValid } from '../utils'
 import { VideoModel } from './video'
-import * as Sequelize from 'sequelize'
 import { VideoRedundancyModel } from '../redundancy/video-redundancy'
 import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type'
 import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
@@ -11,6 +10,7 @@ import { VideoFileModel } from './video-file'
 import { join } from 'path'
 import { sha1 } from '../../helpers/core-utils'
 import { isArrayOf } from '../../helpers/custom-validators/misc'
+import { QueryTypes, Op } from 'sequelize'
 
 @Table({
   tableName: 'videoStreamingPlaylist',
@@ -26,7 +26,7 @@ import { isArrayOf } from '../../helpers/custom-validators/misc'
       fields: [ 'p2pMediaLoaderInfohashes' ],
       using: 'gin'
     }
-  ]
+  ] as any // FIXME: sequelize typings
 })
 export class VideoStreamingPlaylistModel extends Model<VideoStreamingPlaylistModel> {
   @CreatedAt
@@ -46,7 +46,7 @@ export class VideoStreamingPlaylistModel extends Model<VideoStreamingPlaylistMod
 
   @AllowNull(false)
   @Is('VideoStreamingPlaylistInfoHashes', value => throwIfNotValid(value, v => isArrayOf(v, isVideoFileInfoHashValid), 'info hashes'))
-  @Column(DataType.ARRAY(DataType.STRING))
+  @Column({ type: DataType.ARRAY(DataType.STRING) }) // FIXME: typings
   p2pMediaLoaderInfohashes: string[]
 
   @AllowNull(false)
@@ -82,15 +82,13 @@ export class VideoStreamingPlaylistModel extends Model<VideoStreamingPlaylistMod
   static doesInfohashExist (infoHash: string) {
     const query = 'SELECT 1 FROM "videoStreamingPlaylist" WHERE $infoHash = ANY("p2pMediaLoaderInfohashes") LIMIT 1'
     const options = {
-      type: Sequelize.QueryTypes.SELECT,
+      type: QueryTypes.SELECT as QueryTypes.SELECT,
       bind: { infoHash },
       raw: true
     }
 
-    return VideoModel.sequelize.query(query, options)
-              .then(results => {
-                return results.length === 1
-              })
+    return VideoModel.sequelize.query<any>(query, options)
+              .then(results => results.length === 1)
   }
 
   static buildP2PMediaLoaderInfoHashes (playlistUrl: string, videoFiles: VideoFileModel[]) {
@@ -108,7 +106,7 @@ export class VideoStreamingPlaylistModel extends Model<VideoStreamingPlaylistMod
     const query = {
       where: {
         p2pMediaLoaderPeerVersion: {
-          [Sequelize.Op.ne]: P2P_MEDIA_LOADER_PEER_VERSION
+          [Op.ne]: P2P_MEDIA_LOADER_PEER_VERSION
         }
       }
     }
index 9840d17fdcf96a752f7fe9d255ace9b260673b37..329cebd28a6ed37db9d1b477fd10af8b4c325017 100644 (file)
@@ -3,7 +3,18 @@ import { maxBy } from 'lodash'
 import * as magnetUtil from 'magnet-uri'
 import * as parseTorrent from 'parse-torrent'
 import { join } from 'path'
-import * as Sequelize from 'sequelize'
+import {
+  CountOptions,
+  FindOptions,
+  IncludeOptions,
+  ModelIndexesOptions,
+  Op,
+  QueryTypes,
+  ScopeOptions,
+  Sequelize,
+  Transaction,
+  WhereOptions
+} from 'sequelize'
 import {
   AllowNull,
   BeforeDestroy,
@@ -16,8 +27,6 @@ import {
   ForeignKey,
   HasMany,
   HasOne,
-  IFindOptions,
-  IIncludeOptions,
   Is,
   IsInt,
   IsUUID,
@@ -45,7 +54,7 @@ import {
   isVideoStateValid,
   isVideoSupportValid
 } from '../../helpers/custom-validators/videos'
-import { generateImageFromVideoFile, getVideoFileResolution } from '../../helpers/ffmpeg-utils'
+import { getVideoFileResolution } from '../../helpers/ffmpeg-utils'
 import { logger } from '../../helpers/logger'
 import { getServerActor } from '../../helpers/utils'
 import {
@@ -54,11 +63,9 @@ import {
   CONSTRAINTS_FIELDS,
   HLS_REDUNDANCY_DIRECTORY,
   HLS_STREAMING_PLAYLIST_DIRECTORY,
-  PREVIEWS_SIZE,
   REMOTE_SCHEME,
   STATIC_DOWNLOAD_PATHS,
   STATIC_PATHS,
-  THUMBNAILS_SIZE,
   VIDEO_CATEGORIES,
   VIDEO_LANGUAGES,
   VIDEO_LICENCES,
@@ -111,7 +118,7 @@ import { ThumbnailModel } from './thumbnail'
 import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type'
 
 // FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
-const indexes: Sequelize.DefineIndexesOptions[] = [
+const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [
   buildTrigramSearchIndex('video_name_trigram', 'name'),
 
   { fields: [ 'createdAt' ] },
@@ -123,7 +130,7 @@ const indexes: Sequelize.DefineIndexesOptions[] = [
     fields: [ 'originallyPublishedAt' ],
     where: {
       originallyPublishedAt: {
-        [Sequelize.Op.ne]: null
+        [Op.ne]: null
       }
     }
   },
@@ -131,7 +138,7 @@ const indexes: Sequelize.DefineIndexesOptions[] = [
     fields: [ 'category' ], // We don't care videos with an unknown category
     where: {
       category: {
-        [Sequelize.Op.ne]: null
+        [Op.ne]: null
       }
     }
   },
@@ -139,7 +146,7 @@ const indexes: Sequelize.DefineIndexesOptions[] = [
     fields: [ 'licence' ], // We don't care videos with an unknown licence
     where: {
       licence: {
-        [Sequelize.Op.ne]: null
+        [Op.ne]: null
       }
     }
   },
@@ -147,7 +154,7 @@ const indexes: Sequelize.DefineIndexesOptions[] = [
     fields: [ 'language' ], // We don't care videos with an unknown language
     where: {
       language: {
-        [Sequelize.Op.ne]: null
+        [Op.ne]: null
       }
     }
   },
@@ -222,10 +229,10 @@ type AvailableForListIDsOptions = {
 
 @Scopes({
   [ ScopeNames.FOR_API ]: (options: ForAPIOptions) => {
-    const query: IFindOptions<VideoModel> = {
+    const query: FindOptions = {
       where: {
         id: {
-          [ Sequelize.Op.any ]: options.ids
+          [ Op.in ]: options.ids // FIXME: sequelize any seems broken
         }
       },
       include: [
@@ -256,21 +263,21 @@ type AvailableForListIDsOptions = {
     return query
   },
   [ ScopeNames.AVAILABLE_FOR_LIST_IDS ]: (options: AvailableForListIDsOptions) => {
-    const query: IFindOptions<VideoModel> = {
+    const query: FindOptions = {
       raw: true,
       attributes: [ 'id' ],
       where: {
         id: {
-          [ Sequelize.Op.and ]: [
+          [ Op.and ]: [
             {
-              [ Sequelize.Op.notIn ]: Sequelize.literal(
+              [ Op.notIn ]: Sequelize.literal(
                 '(SELECT "videoBlacklist"."videoId" FROM "videoBlacklist")'
               )
             }
           ]
         },
         channelId: {
-          [ Sequelize.Op.notIn ]: Sequelize.literal(
+          [ Op.notIn ]: Sequelize.literal(
             '(' +
               'SELECT id FROM "videoChannel" WHERE "accountId" IN (' +
                 buildBlockedAccountSQL(options.serverAccountId, options.user ? options.user.Account.id : undefined) +
@@ -288,12 +295,12 @@ type AvailableForListIDsOptions = {
         // Always list public videos
         privacy: VideoPrivacy.PUBLIC,
         // Always list published videos, or videos that are being transcoded but on which we don't want to wait for transcoding
-        [ Sequelize.Op.or ]: [
+        [ Op.or ]: [
           {
             state: VideoState.PUBLISHED
           },
           {
-            [ Sequelize.Op.and ]: {
+            [ Op.and ]: {
               state: VideoState.TO_TRANSCODE,
               waitTranscoding: false
             }
@@ -318,7 +325,7 @@ type AvailableForListIDsOptions = {
     }
 
     if (options.filter || options.accountId || options.videoChannelId) {
-      const videoChannelInclude: IIncludeOptions = {
+      const videoChannelInclude: IncludeOptions = {
         attributes: [],
         model: VideoChannelModel.unscoped(),
         required: true
@@ -331,7 +338,7 @@ type AvailableForListIDsOptions = {
       }
 
       if (options.filter || options.accountId) {
-        const accountInclude: IIncludeOptions = {
+        const accountInclude: IncludeOptions = {
           attributes: [],
           model: AccountModel.unscoped(),
           required: true
@@ -371,8 +378,8 @@ type AvailableForListIDsOptions = {
 
       // Force actorId to be a number to avoid SQL injections
       const actorIdNumber = parseInt(options.followerActorId.toString(), 10)
-      query.where[ 'id' ][ Sequelize.Op.and ].push({
-        [ Sequelize.Op.in ]: Sequelize.literal(
+      query.where[ 'id' ][ Op.and ].push({
+        [ Op.in ]: Sequelize.literal(
           '(' +
           'SELECT "videoShare"."videoId" AS "id" FROM "videoShare" ' +
           'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "videoShare"."actorId" ' +
@@ -391,8 +398,8 @@ type AvailableForListIDsOptions = {
     }
 
     if (options.withFiles === true) {
-      query.where[ 'id' ][ Sequelize.Op.and ].push({
-        [ Sequelize.Op.in ]: Sequelize.literal(
+      query.where[ 'id' ][ Op.and ].push({
+        [ Op.in ]: Sequelize.literal(
           '(SELECT "videoId" FROM "videoFile")'
         )
       })
@@ -406,8 +413,8 @@ type AvailableForListIDsOptions = {
       }
 
       if (options.tagsOneOf) {
-        query.where[ 'id' ][ Sequelize.Op.and ].push({
-          [ Sequelize.Op.in ]: Sequelize.literal(
+        query.where[ 'id' ][ Op.and ].push({
+          [ Op.in ]: Sequelize.literal(
             '(' +
             'SELECT "videoId" FROM "videoTag" ' +
             'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
@@ -418,8 +425,8 @@ type AvailableForListIDsOptions = {
       }
 
       if (options.tagsAllOf) {
-        query.where[ 'id' ][ Sequelize.Op.and ].push({
-          [ Sequelize.Op.in ]: Sequelize.literal(
+        query.where[ 'id' ][ Op.and ].push({
+          [ Op.in ]: Sequelize.literal(
             '(' +
             'SELECT "videoId" FROM "videoTag" ' +
             'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
@@ -437,19 +444,19 @@ type AvailableForListIDsOptions = {
 
     if (options.categoryOneOf) {
       query.where[ 'category' ] = {
-        [ Sequelize.Op.or ]: options.categoryOneOf
+        [ Op.or ]: options.categoryOneOf
       }
     }
 
     if (options.licenceOneOf) {
       query.where[ 'licence' ] = {
-        [ Sequelize.Op.or ]: options.licenceOneOf
+        [ Op.or ]: options.licenceOneOf
       }
     }
 
     if (options.languageOneOf) {
       query.where[ 'language' ] = {
-        [ Sequelize.Op.or ]: options.languageOneOf
+        [ Op.or ]: options.languageOneOf
       }
     }
 
@@ -498,7 +505,7 @@ type AvailableForListIDsOptions = {
           }
         ]
       }
-    ]
+    ] as any // FIXME: sequelize typings
   },
   [ ScopeNames.WITH_ACCOUNT_DETAILS ]: {
     include: [
@@ -550,7 +557,7 @@ type AvailableForListIDsOptions = {
           }
         ]
       }
-    ]
+    ] as any // FIXME: sequelize typings
   },
   [ ScopeNames.WITH_TAGS ]: {
     include: [ () => TagModel ]
@@ -656,19 +663,19 @@ export class VideoModel extends Model<VideoModel> {
 
   @AllowNull(true)
   @Default(null)
-  @Is('VideoCategory', value => throwIfNotValid(value, isVideoCategoryValid, 'category'))
+  @Is('VideoCategory', value => throwIfNotValid(value, isVideoCategoryValid, 'category', true))
   @Column
   category: number
 
   @AllowNull(true)
   @Default(null)
-  @Is('VideoLicence', value => throwIfNotValid(value, isVideoLicenceValid, 'licence'))
+  @Is('VideoLicence', value => throwIfNotValid(value, isVideoLicenceValid, 'licence', true))
   @Column
   licence: number
 
   @AllowNull(true)
   @Default(null)
-  @Is('VideoLanguage', value => throwIfNotValid(value, isVideoLanguageValid, 'language'))
+  @Is('VideoLanguage', value => throwIfNotValid(value, isVideoLanguageValid, 'language', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.LANGUAGE.max))
   language: string
 
@@ -684,13 +691,13 @@ export class VideoModel extends Model<VideoModel> {
 
   @AllowNull(true)
   @Default(null)
-  @Is('VideoDescription', value => throwIfNotValid(value, isVideoDescriptionValid, 'description'))
+  @Is('VideoDescription', value => throwIfNotValid(value, isVideoDescriptionValid, 'description', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max))
   description: string
 
   @AllowNull(true)
   @Default(null)
-  @Is('VideoSupport', value => throwIfNotValid(value, isVideoSupportValid, 'support'))
+  @Is('VideoSupport', value => throwIfNotValid(value, isVideoSupportValid, 'support', true))
   @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.SUPPORT.max))
   support: string
 
@@ -754,7 +761,7 @@ export class VideoModel extends Model<VideoModel> {
   updatedAt: Date
 
   @AllowNull(false)
-  @Default(Sequelize.NOW)
+  @Default(DataType.NOW)
   @Column
   publishedAt: Date
 
@@ -999,12 +1006,12 @@ export class VideoModel extends Model<VideoModel> {
       distinct: true,
       offset: start,
       limit: count,
-      order: getVideoSort('createdAt', [ 'Tags', 'name', 'ASC' ]),
+      order: getVideoSort('createdAt', [ 'Tags', 'name', 'ASC' ] as any), // FIXME: sequelize typings
       where: {
         id: {
-          [ Sequelize.Op.in ]: Sequelize.literal('(' + rawQuery + ')')
+          [ Op.in ]: Sequelize.literal('(' + rawQuery + ')')
         },
-        [ Sequelize.Op.or ]: [
+        [ Op.or ]: [
           { privacy: VideoPrivacy.PUBLIC },
           { privacy: VideoPrivacy.UNLISTED }
         ]
@@ -1021,10 +1028,10 @@ export class VideoModel extends Model<VideoModel> {
           required: false,
           // We only want videos shared by this actor
           where: {
-            [ Sequelize.Op.and ]: [
+            [ Op.and ]: [
               {
                 id: {
-                  [ Sequelize.Op.not ]: null
+                  [ Op.not ]: null
                 }
               },
               {
@@ -1070,13 +1077,13 @@ export class VideoModel extends Model<VideoModel> {
     return Bluebird.all([
       // FIXME: typing issue
       VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findAll(query as any),
-      VideoModel.sequelize.query(rawCountQuery, { type: Sequelize.QueryTypes.SELECT })
+      VideoModel.sequelize.query<{ total: number }>(rawCountQuery, { type: QueryTypes.SELECT })
     ]).then(([ rows, totals ]) => {
       // totals: totalVideos + totalVideoShares
       let totalVideos = 0
       let totalVideoShares = 0
-      if (totals[ 0 ]) totalVideos = parseInt(totals[ 0 ].total, 10)
-      if (totals[ 1 ]) totalVideoShares = parseInt(totals[ 1 ].total, 10)
+      if (totals[ 0 ]) totalVideos = parseInt(totals[ 0 ].total + '', 10)
+      if (totals[ 1 ]) totalVideoShares = parseInt(totals[ 1 ].total + '', 10)
 
       const total = totalVideos + totalVideoShares
       return {
@@ -1087,7 +1094,7 @@ export class VideoModel extends Model<VideoModel> {
   }
 
   static listUserVideosForApi (accountId: number, start: number, count: number, sort: string, withFiles = false) {
-    const query: IFindOptions<VideoModel> = {
+    const query: FindOptions = {
       offset: start,
       limit: count,
       order: getVideoSort(sort),
@@ -1158,7 +1165,7 @@ export class VideoModel extends Model<VideoModel> {
       throw new Error('Try to filter all-local but no user has not the see all videos right')
     }
 
-    const query: IFindOptions<VideoModel> = {
+    const query: FindOptions = {
       offset: options.start,
       limit: options.count,
       order: getVideoSort(options.sort)
@@ -1225,8 +1232,8 @@ export class VideoModel extends Model<VideoModel> {
     if (options.startDate || options.endDate) {
       const publishedAtRange = {}
 
-      if (options.startDate) publishedAtRange[ Sequelize.Op.gte ] = options.startDate
-      if (options.endDate) publishedAtRange[ Sequelize.Op.lte ] = options.endDate
+      if (options.startDate) publishedAtRange[ Op.gte ] = options.startDate
+      if (options.endDate) publishedAtRange[ Op.lte ] = options.endDate
 
       whereAnd.push({ publishedAt: publishedAtRange })
     }
@@ -1234,8 +1241,8 @@ export class VideoModel extends Model<VideoModel> {
     if (options.originallyPublishedStartDate || options.originallyPublishedEndDate) {
       const originallyPublishedAtRange = {}
 
-      if (options.originallyPublishedStartDate) originallyPublishedAtRange[ Sequelize.Op.gte ] = options.originallyPublishedStartDate
-      if (options.originallyPublishedEndDate) originallyPublishedAtRange[ Sequelize.Op.lte ] = options.originallyPublishedEndDate
+      if (options.originallyPublishedStartDate) originallyPublishedAtRange[ Op.gte ] = options.originallyPublishedStartDate
+      if (options.originallyPublishedEndDate) originallyPublishedAtRange[ Op.lte ] = options.originallyPublishedEndDate
 
       whereAnd.push({ originallyPublishedAt: originallyPublishedAtRange })
     }
@@ -1243,8 +1250,8 @@ export class VideoModel extends Model<VideoModel> {
     if (options.durationMin || options.durationMax) {
       const durationRange = {}
 
-      if (options.durationMin) durationRange[ Sequelize.Op.gte ] = options.durationMin
-      if (options.durationMax) durationRange[ Sequelize.Op.lte ] = options.durationMax
+      if (options.durationMin) durationRange[ Op.gte ] = options.durationMin
+      if (options.durationMax) durationRange[ Op.lte ] = options.durationMax
 
       whereAnd.push({ duration: durationRange })
     }
@@ -1256,7 +1263,7 @@ export class VideoModel extends Model<VideoModel> {
       whereAnd.push(
         {
           id: {
-            [ Sequelize.Op.in ]: Sequelize.literal(
+            [ Op.in ]: Sequelize.literal(
               '(' +
               'SELECT "video"."id" FROM "video" ' +
               'WHERE ' +
@@ -1282,7 +1289,7 @@ export class VideoModel extends Model<VideoModel> {
       )
     }
 
-    const query: IFindOptions<VideoModel> = {
+    const query: FindOptions = {
       attributes: {
         include: attributesInclude
       },
@@ -1290,7 +1297,7 @@ export class VideoModel extends Model<VideoModel> {
       limit: options.count,
       order: getVideoSort(options.sort),
       where: {
-        [ Sequelize.Op.and ]: whereAnd
+        [ Op.and ]: whereAnd
       }
     }
 
@@ -1312,7 +1319,7 @@ export class VideoModel extends Model<VideoModel> {
     return VideoModel.getAvailableForApi(query, queryOptions)
   }
 
-  static load (id: number | string, t?: Sequelize.Transaction) {
+  static load (id: number | string, t?: Transaction) {
     const where = buildWhereIdOrUUID(id)
     const options = {
       where,
@@ -1322,7 +1329,7 @@ export class VideoModel extends Model<VideoModel> {
     return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options)
   }
 
-  static loadWithRights (id: number | string, t?: Sequelize.Transaction) {
+  static loadWithRights (id: number | string, t?: Transaction) {
     const where = buildWhereIdOrUUID(id)
     const options = {
       where,
@@ -1336,7 +1343,7 @@ export class VideoModel extends Model<VideoModel> {
     ]).findOne(options)
   }
 
-  static loadOnlyId (id: number | string, t?: Sequelize.Transaction) {
+  static loadOnlyId (id: number | string, t?: Transaction) {
     const where = buildWhereIdOrUUID(id)
 
     const options = {
@@ -1348,7 +1355,7 @@ export class VideoModel extends Model<VideoModel> {
     return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options)
   }
 
-  static loadWithFiles (id: number, t?: Sequelize.Transaction, logging?: boolean) {
+  static loadWithFiles (id: number, t?: Transaction, logging?: boolean) {
     return VideoModel.scope([
       ScopeNames.WITH_FILES,
       ScopeNames.WITH_STREAMING_PLAYLISTS,
@@ -1366,8 +1373,8 @@ export class VideoModel extends Model<VideoModel> {
     return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options)
   }
 
-  static loadByUrl (url: string, transaction?: Sequelize.Transaction) {
-    const query: IFindOptions<VideoModel> = {
+  static loadByUrl (url: string, transaction?: Transaction) {
+    const query: FindOptions = {
       where: {
         url
       },
@@ -1377,8 +1384,8 @@ export class VideoModel extends Model<VideoModel> {
     return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(query)
   }
 
-  static loadByUrlAndPopulateAccount (url: string, transaction?: Sequelize.Transaction) {
-    const query: IFindOptions<VideoModel> = {
+  static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction) {
+    const query: FindOptions = {
       where: {
         url
       },
@@ -1393,11 +1400,11 @@ export class VideoModel extends Model<VideoModel> {
     ]).findOne(query)
   }
 
-  static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Sequelize.Transaction, userId?: number) {
+  static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Transaction, userId?: number) {
     const where = buildWhereIdOrUUID(id)
 
     const options = {
-      order: [ [ 'Tags', 'name', 'ASC' ] ],
+      order: [ [ 'Tags', 'name', 'ASC' ] ] as any, // FIXME: sequelize typings
       where,
       transaction: t
     }
@@ -1421,11 +1428,11 @@ export class VideoModel extends Model<VideoModel> {
       .findOne(options)
   }
 
-  static loadForGetAPI (id: number | string, t?: Sequelize.Transaction, userId?: number) {
+  static loadForGetAPI (id: number | string, t?: Transaction, userId?: number) {
     const where = buildWhereIdOrUUID(id)
 
     const options = {
-      order: [ [ 'Tags', 'name', 'ASC' ] ],
+      order: [ [ 'Tags', 'name', 'ASC' ] ] as any, // FIXME: sequelize typings
       where,
       transaction: t
     }
@@ -1489,7 +1496,7 @@ export class VideoModel extends Model<VideoModel> {
     'LIMIT 1'
 
     const options = {
-      type: Sequelize.QueryTypes.SELECT,
+      type: QueryTypes.SELECT,
       bind: { followerActorId, videoId },
       raw: true
     }
@@ -1509,14 +1516,14 @@ export class VideoModel extends Model<VideoModel> {
       includeLocalVideos: true
     }
 
-    const query: IFindOptions<VideoModel> = {
+    const query: FindOptions = {
       attributes: [ field ],
       limit: count,
       group: field,
       having: Sequelize.where(Sequelize.fn('COUNT', Sequelize.col(field)), {
-        [ Sequelize.Op.gte ]: threshold
+        [ Op.gte ]: threshold
       }) as any, // FIXME: typings
-      order: [ this.sequelize.random() ]
+      order: [ (this.sequelize as any).random() ]
     }
 
     return VideoModel.scope({ method: [ ScopeNames.AVAILABLE_FOR_LIST_IDS, scopeOptions ] })
@@ -1532,7 +1539,7 @@ export class VideoModel extends Model<VideoModel> {
       required: false,
       where: {
         startDate: {
-          [ Sequelize.Op.gte ]: new Date(new Date().getTime() - (24 * 3600 * 1000) * trendingDays)
+          [ Op.gte ]: new Date(new Date().getTime() - (24 * 3600 * 1000) * trendingDays)
         }
       }
     }
@@ -1549,11 +1556,11 @@ export class VideoModel extends Model<VideoModel> {
   }
 
   private static async getAvailableForApi (
-    query: IFindOptions<VideoModel>,
+    query: FindOptions,
     options: AvailableForListIDsOptions,
     countVideos = true
   ) {
-    const idsScope = {
+    const idsScope: ScopeOptions = {
       method: [
         ScopeNames.AVAILABLE_FOR_LIST_IDS, options
       ]
@@ -1561,8 +1568,8 @@ export class VideoModel extends Model<VideoModel> {
 
     // Remove trending sort on count, because it uses a group by
     const countOptions = Object.assign({}, options, { trendingDays: undefined })
-    const countQuery = Object.assign({}, query, { attributes: undefined, group: undefined })
-    const countScope = {
+    const countQuery: CountOptions = Object.assign({}, query, { attributes: undefined, group: undefined })
+    const countScope: ScopeOptions = {
       method: [
         ScopeNames.AVAILABLE_FOR_LIST_IDS, countOptions
       ]
@@ -1576,7 +1583,7 @@ export class VideoModel extends Model<VideoModel> {
 
     if (ids.length === 0) return { data: [], total: count }
 
-    const secondQuery: IFindOptions<VideoModel> = {
+    const secondQuery: FindOptions = {
       offset: 0,
       limit: query.limit,
       attributes: query.attributes,
index b281471ce1494de01ac2431520bc4072f9c18b97..7aebffc3234cad91905270d7e421f229641dfa56 100644 (file)
@@ -1,6 +1,6 @@
-import * as Sequelize from 'sequelize'
+import { QueryTypes, Sequelize } from 'sequelize'
 
-let sequelizes: { [ id: number ]: Sequelize.Sequelize } = {}
+let sequelizes: { [ id: number ]: Sequelize } = {}
 
 function getSequelize (serverNumber: number) {
   if (sequelizes[serverNumber]) return sequelizes[serverNumber]
@@ -27,7 +27,7 @@ function getSequelize (serverNumber: number) {
 function setActorField (serverNumber: number, to: string, field: string, value: string) {
   const seq = getSequelize(serverNumber)
 
-  const options = { type: Sequelize.QueryTypes.UPDATE }
+  const options = { type: QueryTypes.UPDATE }
 
   return seq.query(`UPDATE actor SET "${field}" = '${value}' WHERE url = '${to}'`, options)
 }
@@ -35,7 +35,7 @@ function setActorField (serverNumber: number, to: string, field: string, value:
 function setVideoField (serverNumber: number, uuid: string, field: string, value: string) {
   const seq = getSequelize(serverNumber)
 
-  const options = { type: Sequelize.QueryTypes.UPDATE }
+  const options = { type: QueryTypes.UPDATE }
 
   return seq.query(`UPDATE video SET "${field}" = '${value}' WHERE uuid = '${uuid}'`, options)
 }
@@ -43,7 +43,7 @@ function setVideoField (serverNumber: number, uuid: string, field: string, value
 function setPlaylistField (serverNumber: number, uuid: string, field: string, value: string) {
   const seq = getSequelize(serverNumber)
 
-  const options = { type: Sequelize.QueryTypes.UPDATE }
+  const options = { type: QueryTypes.UPDATE }
 
   return seq.query(`UPDATE "videoPlaylist" SET "${field}" = '${value}' WHERE uuid = '${uuid}'`, options)
 }
@@ -54,12 +54,13 @@ async function countVideoViewsOf (serverNumber: number, uuid: string) {
   // tslint:disable
   const query = `SELECT SUM("videoView"."views") AS "total" FROM "videoView" INNER JOIN "video" ON "video"."id" = "videoView"."videoId" WHERE "video"."uuid" = '${uuid}'`
 
-  const options = { type: Sequelize.QueryTypes.SELECT }
-  const [ { total } ] = await seq.query(query, options)
+  const options = { type: QueryTypes.SELECT as QueryTypes.SELECT }
+  const [ { total } ] = await seq.query<{ total: number }>(query, options)
 
   if (!total) return 0
 
-  return parseInt(total, 10)
+  // FIXME: check if we really need parseInt
+  return parseInt(total + '', 10)
 }
 
 async function closeAllSequelize (servers: any[]) {
index 8b4f07509a8505fbc5c5af9491cd98897cbefd35..dd1de4fa0e67fe288b5b66a7fbe5f1e6953212fe 100644 (file)
--- a/yarn.lock
+++ b/yarn.lock
@@ -38,7 +38,7 @@
   dependencies:
     "@types/node" "*"
 
-"@types/bluebird@*", "@types/bluebird@3.5.18", "@types/bluebird@3.5.21":
+"@types/bluebird@*", "@types/bluebird@3.5.21":
   version "3.5.21"
   resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.21.tgz#567615589cc913e84a28ecf9edb031732bdf2634"
   integrity sha512-6UNEwyw+6SGMC/WMI0ld0PS4st7Qq51qgguFrFizOSpGvZiqe9iswztFSdZvwJBEhLOy2JaxNE6VC7yMAlbfyQ==
   dependencies:
     "@types/node" "*"
 
-"@types/continuation-local-storage@*":
-  version "3.2.1"
-  resolved "https://registry.yarnpkg.com/@types/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz#a33e0df9dce9b424d1c98fc4fdebd8578dceec7e"
-  integrity sha1-oz4N+dzptCTRyY/E/evYV43O7H4=
-  dependencies:
-    "@types/node" "*"
-
 "@types/cookiejar@*":
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.1.tgz#90b68446364baf9efd8e8349bb36bd3852b75b80"
   dependencies:
     "@types/node" "*"
 
-"@types/geojson@^1.0.0":
-  version "1.0.6"
-  resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-1.0.6.tgz#3e02972728c69248c2af08d60a48cbb8680fffdf"
-  integrity sha512-Xqg/lIZMrUd0VRmSRbCAewtwGZiAk3mEUDvV4op1tGl+LvyPcb/MIOSxTl9z+9+J+R4/vpjiCAT4xeKzH9ji1w==
-
 "@types/ioredis@*":
   version "4.0.10"
   resolved "https://registry.yarnpkg.com/@types/ioredis/-/ioredis-4.0.10.tgz#ca8bd95ca7d5fee32cbc5a0bf92fc29264bee237"
   dependencies:
     "@types/node" "*"
 
-"@types/lodash@*", "@types/lodash@^4.14.64":
+"@types/lodash@^4.14.64":
   version "4.14.123"
   resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.123.tgz#39be5d211478c8dd3bdae98ee75bb7efe4abfe4d"
   integrity sha512-pQvPkc4Nltyx7G1Ww45OjVqUsJP4UsZm+GWJpigXgkikZqJgRm4c48g027o6tdgubWHwFRF15iFd+Y4Pmqv6+Q==
   resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.0.tgz#b0df8d6ef9b5001b2be3a94d909ce3c29a80f9e1"
   integrity sha512-rx29MMkRdVmzunmiA4lzBYJNnXsW/PhG4kMBy2ATsYaDjGGR75dCFEVVROKpNwlVdcUX3xxlghKQOeDPBJobng==
 
-"@types/node@6.0.41":
-  version "6.0.41"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.41.tgz#578cf53aaec65887bcaf16792f8722932e8ff8ea"
-  integrity sha1-V4z1Oq7GWIe8rxZ5L4ciky6P+Oo=
-
 "@types/node@^10.0.8":
   version "10.14.4"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.4.tgz#1c586b991457cbb58fef51bc4e0cfcfa347714b5"
     "@types/node" "*"
     "@types/tough-cookie" "*"
 
-"@types/sequelize@4.27.24":
-  version "4.27.24"
-  resolved "https://registry.yarnpkg.com/@types/sequelize/-/sequelize-4.27.24.tgz#7d593c062c368f570c68b0217f5c1d4c892ead48"
-  integrity sha512-5uMFsMa/0hU/7/8znyfBKSJy2Mbd57uRpYk5X1+Phz9dN0MRZLbTbj1JMeB3CJ4R9b1coNQGfp2kXh4OjI9UyA==
-  dependencies:
-    "@types/bluebird" "*"
-    "@types/continuation-local-storage" "*"
-    "@types/lodash" "*"
-    "@types/validator" "*"
-
 "@types/serve-static@*":
   version "1.13.2"
   resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48"
   resolved "https://registry.yarnpkg.com/@types/tv4/-/tv4-1.2.29.tgz#4c6d2222b03245dd2104f4fd67f54d1658985911"
   integrity sha512-NtJmi+XbYocrLb5Au4Q64srX4FlCPDvrSF/OnK3H0QJwrw40tIUoQPDoUHnZ5wpAB2KThtVyeS+kOEQyZabORg==
 
-"@types/validator@*", "@types/validator@^10.9.0":
+"@types/validator@^10.9.0":
   version "10.11.0"
   resolved "https://registry.yarnpkg.com/@types/validator/-/validator-10.11.0.tgz#aae9009ce28cc4f878e32c34d3900a81193c98d5"
   integrity sha512-i1aY7RKb6HmQIEnK0cBmUZUp1URx0riIHw/GYNoZ46Su0GWfLiDmMI8zMRmaauMnOTg2bQag0qfwcyUFC9Tn+A==
@@ -562,6 +535,11 @@ any-observable@^0.3.0:
   resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b"
   integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==
 
+any-promise@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
+  integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
+
 anymatch@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
@@ -1033,7 +1011,7 @@ bluebird@^2.10.0:
   resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
   integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=
 
-bluebird@^3.0.5, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.3:
+bluebird@^3.0.5, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.3:
   version "3.5.3"
   resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7"
   integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==
@@ -1992,7 +1970,7 @@ debug@2.3.3:
   dependencies:
     ms "0.7.2"
 
-debug@2.6.9, debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
+debug@2.6.9, debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3:
   version "2.6.9"
   resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
   integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@@ -2013,7 +1991,7 @@ debug@3.2.6, debug@^3.1.0:
   dependencies:
     ms "^2.1.1"
 
-debug@^4.0.1, debug@^4.1.0, debug@~4.1.0:
+debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
   integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
@@ -2154,7 +2132,7 @@ depd@2.0.0:
   resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
   integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
 
-depd@^1.1.0, depd@~1.1.0, depd@~1.1.2:
+depd@~1.1.0, depd@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
   integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
@@ -2548,11 +2526,6 @@ es6-set@~0.1.5:
     es6-symbol "3.1.1"
     event-emitter "~0.3.5"
 
-es6-shim@0.35.3:
-  version "0.35.3"
-  resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.3.tgz#9bfb7363feffff87a6cdb6cd93e405ec3c4b6f26"
-  integrity sha1-m/tzY/7//4emzbbNk+QF7DxLbyY=
-
 es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1:
   version "3.1.1"
   resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
@@ -3295,11 +3268,6 @@ generate-object-property@^1.1.0:
   dependencies:
     is-property "^1.0.0"
 
-generic-pool@^3.4.0:
-  version "3.7.1"
-  resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.7.1.tgz#36fe5bb83e7e0e032e5d32cd05dc00f5ff119aa8"
-  integrity sha512-ug6DAZoNgWm6q5KhPFA+hzXfBLFQu5sTXxPpv44DmE0A2g+CiHoq9LTVdkXpZMkYVMoGw83F6W+WT0h0MFMK/w==
-
 genfun@^5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537"
@@ -4955,7 +4923,7 @@ lodash@=3.10.1:
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
   integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=
 
-lodash@^4.0.0, lodash@^4.17.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.3.0, lodash@~4.17.10:
+lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.3.0, lodash@~4.17.10:
   version "4.17.11"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
   integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
@@ -5376,14 +5344,14 @@ mocha@^6.0.0:
     yargs-parser "11.1.1"
     yargs-unparser "1.5.0"
 
-moment-timezone@^0.5.14, moment-timezone@^0.5.23:
+moment-timezone@^0.5.21, moment-timezone@^0.5.23:
   version "0.5.23"
   resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.23.tgz#7cbb00db2c14c71b19303cb47b0fb0a6d8651463"
   integrity sha512-WHFH85DkCfiNMDX5D3X7hpNH3/PUhjTGcD0U1SgfBGZxJ3qUmJh5FdvaFjcClxOvB3rzdfj4oRffbI38jEnC1w==
   dependencies:
     moment ">= 2.9.0"
 
-"moment@>= 2.9.0", moment@^2.20.0:
+"moment@>= 2.9.0", moment@^2.24.0:
   version "2.24.0"
   resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
   integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
@@ -7272,13 +7240,12 @@ ret@~0.1.10:
   resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
   integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
 
-retry-as-promised@^2.3.2:
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-2.3.2.tgz#cd974ee4fd9b5fe03cbf31871ee48221c07737b7"
-  integrity sha1-zZdO5P2bX+A8vzGHHuSCIcB3N7c=
+retry-as-promised@^3.1.0:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-3.2.0.tgz#769f63d536bec4783549db0777cb56dadd9d8543"
+  integrity sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==
   dependencies:
-    bluebird "^3.4.6"
-    debug "^2.6.9"
+    any-promise "^1.3.0"
 
 retry@^0.10.0:
   version "0.10.1"
@@ -7487,39 +7454,40 @@ send@0.16.2:
     range-parser "~1.2.0"
     statuses "~1.4.0"
 
-sequelize-typescript@0.6.7:
-  version "0.6.7"
-  resolved "https://registry.yarnpkg.com/sequelize-typescript/-/sequelize-typescript-0.6.7.tgz#372be979cbae060c554fdbaf2c2d8c93a0283303"
-  integrity sha512-ae21Gq9VOVXlIjnh2vLdL42Kev6r4LC82xOQ2fXo0lHzQvjFeH8/GaWUlpvYv57AOgc+ZnElbYFbSLKdT9ue0w==
+sequelize-pool@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-1.0.2.tgz#89c767882bbdb8a41dac66922ed9820939a5401e"
+  integrity sha512-VMKl/gCCdIvB1gFZ7p+oqLFEyZEz3oMMYjkKvfEC7GoO9bBcxmfOOU9RdkoltfXGgBZFigSChihRly2gKtsh2w==
+  dependencies:
+    bluebird "^3.5.3"
+
+sequelize-typescript@^1.0.0-beta.1:
+  version "1.0.0-beta.1"
+  resolved "https://registry.yarnpkg.com/sequelize-typescript/-/sequelize-typescript-1.0.0-beta.1.tgz#402279fec52669cbd78ecbf50e189638483a7360"
+  integrity sha512-xD28kqa1rIKujlmgA4hWQgtwFfRM6tLv1/mnZOrOFEZxvSWazUbTzqGB7OZydZDNj3iJnyrV1l6i6HOfvrpvEw==
   dependencies:
-    "@types/bluebird" "3.5.18"
-    "@types/node" "6.0.41"
-    "@types/sequelize" "4.27.24"
-    es6-shim "0.35.3"
     glob "7.1.2"
 
-sequelize@4.42.0:
-  version "4.42.0"
-  resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-4.42.0.tgz#439467ba7bfe7d5afcc56d62b3e091860fbf18f3"
-  integrity sha512-qxAYnX4rcv7PbNtEidb56REpxNJCdbN0qyk1jb3+e6sE7OrmS0nYMU+MFVbNTJtZfSpOEEL1TX0TkMw+wzZBxg==
+sequelize@5.6.1:
+  version "5.6.1"
+  resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-5.6.1.tgz#fc22306109fb2504a6573edfb3c469ec86fae873"
+  integrity sha512-QsXUDar6ow0HrF9BtnHRaNumu6qRYb97dfwvez/Z5guH3i6w6k8+bp6gP3VCiDC+2qX+jQIyrYohKg9evy8GFg==
   dependencies:
     bluebird "^3.5.0"
     cls-bluebird "^2.1.0"
-    debug "^3.1.0"
-    depd "^1.1.0"
+    debug "^4.1.1"
     dottie "^2.0.0"
-    generic-pool "^3.4.0"
     inflection "1.12.0"
-    lodash "^4.17.1"
-    moment "^2.20.0"
-    moment-timezone "^0.5.14"
-    retry-as-promised "^2.3.2"
-    semver "^5.5.0"
-    terraformer-wkt-parser "^1.1.2"
+    lodash "^4.17.11"
+    moment "^2.24.0"
+    moment-timezone "^0.5.21"
+    retry-as-promised "^3.1.0"
+    semver "^5.6.0"
+    sequelize-pool "^1.0.2"
     toposort-class "^1.0.1"
     uuid "^3.2.1"
-    validator "^10.4.0"
-    wkx "^0.4.1"
+    validator "^10.11.0"
+    wkx "^0.4.6"
 
 serve-static@1.13.2:
   version "1.13.2"
@@ -8398,21 +8366,6 @@ term-size@^1.2.0:
   dependencies:
     execa "^0.7.0"
 
-terraformer-wkt-parser@^1.1.2:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/terraformer-wkt-parser/-/terraformer-wkt-parser-1.2.0.tgz#c9d6ac3dff25f4c0bd344e961f42694961834c34"
-  integrity sha512-QU3iA54St5lF8Za1jg1oj4NYc8sn5tCZ08aNSWDeGzrsaV48eZk1iAVWasxhNspYBoCqdHuoot1pUTUrE1AJ4w==
-  dependencies:
-    "@types/geojson" "^1.0.0"
-    terraformer "~1.0.5"
-
-terraformer@~1.0.5:
-  version "1.0.9"
-  resolved "https://registry.yarnpkg.com/terraformer/-/terraformer-1.0.9.tgz#77851fef4a49c90b345dc53cf26809fdf29dcda6"
-  integrity sha512-YlmQ1fsMWTkKGDGibCRWgmLzrpDRUr63Q025LJ/taYQ6j1Yb8q9McKF7NBi6ACAyUXO6F/bl9w6v4MY307y5Ag==
-  optionalDependencies:
-    "@types/geojson" "^1.0.0"
-
 text-hex@1.0.x:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5"
@@ -9002,7 +8955,7 @@ validate-npm-package-name@^3.0.0, validate-npm-package-name@~3.0.0:
   dependencies:
     builtins "^1.0.3"
 
-validator@^10.0.0, validator@^10.2.0, validator@^10.4.0:
+validator@^10.0.0, validator@^10.11.0, validator@^10.2.0, validator@^10.4.0:
   version "10.11.0"
   resolved "https://registry.yarnpkg.com/validator/-/validator-10.11.0.tgz#003108ea6e9a9874d31ccc9e5006856ccd76b228"
   integrity sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==
@@ -9172,7 +9125,7 @@ winston@3.2.1:
     triple-beam "^1.3.0"
     winston-transport "^4.3.0"
 
-wkx@^0.4.1:
+wkx@^0.4.6:
   version "0.4.6"
   resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.4.6.tgz#228ab592e6457382ea6fb79fc825058d07fce523"
   integrity sha512-LHxXlzRCYQXA9ZHgs8r7Gafh0gVOE8o3QmudM1PIkOdkXXjW7Thcl+gb2P2dRuKgW8cqkitCRZkkjtmWzpHi7A==