Move to eslint

pull/2456/head contain
Chocobozzz 2020-01-31 16:56:52 +01:00
parent a22046d166
commit a15871560f
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
390 changed files with 3950 additions and 3615 deletions

88
.eslintrc.json Normal file
View File

@ -0,0 +1,88 @@
{
"extends": "standard-with-typescript",
"rules": {
"eol-last": [
"error",
"always"
],
"indent": "off",
"no-lone-blocks": "off",
"no-mixed-operators": "off",
"max-len": [
"error",
{
"code": 140
}
],
"array-bracket-spacing": [
"error",
"always"
],
"quote-props": [
"error",
"consistent-as-needed"
],
"padded-blocks": "off",
"no-async-promise-executor": "off",
"dot-notation": "off",
"promise/param-names": "off",
"import/first": "off",
"operator-linebreak": [
"error",
"after",
{
"overrides": {
"?": "before",
":": "before"
}
}
],
"@typescript-eslint/indent": [
"error",
2,
{
"SwitchCase": 1,
"MemberExpression": "off"
}
],
"@typescript-eslint/consistent-type-assertions": [
"error",
{
"assertionStyle": "as"
}
],
"@typescript-eslint/array-type": [
"error",
{
"default": "array"
}
],
"@typescript-eslint/restrict-template-expressions": [
"off",
{
"allowNumber": "true"
}
],
"@typescript-eslint/quotes": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/promise-function-async": "off",
"@typescript-eslint/no-dynamic-delete": "off",
"@typescript-eslint/strict-boolean-expressions": "off",
"@typescript-eslint/consistent-type-definitions": "off",
"@typescript-eslint/no-misused-promises": "off",
"@typescript-eslint/no-namespace": "off",
"@typescript-eslint/no-extraneous-class": "off",
// bugged but useful
"@typescript-eslint/restrict-plus-operands": "off"
},
"ignorePatterns": [
"node_modules/"
],
"parserOptions": {
"project": [
"./tsconfig.json",
"./server/tools/tsconfig.json"
]
}
}

View File

@ -63,7 +63,7 @@
"ng": "ng",
"nodemon": "nodemon",
"ts-node": "ts-node",
"tslint": "tslint",
"eslint": "eslint",
"concurrently": "concurrently",
"mocha-parallel-tests": "mocha-parallel-tests",
"sasslint": "sass-lint --verbose --no-exit",
@ -96,7 +96,7 @@
"express": "^4.12.4",
"express-oauth-server": "^2.0.0",
"express-rate-limit": "^4.0.4",
"express-validator": "^6.1.1",
"express-validator": "^6.4.0",
"flat": "^5.0.0",
"fluent-ffmpeg": "^2.1.0",
"fs-extra": "^8.0.1",
@ -139,7 +139,7 @@
"webtorrent": "^0.107.16",
"winston": "3.2.1",
"ws": "^7.0.0",
"youtube-dl": "^3.0.1"
"youtube-dl": "^3.0.2"
},
"devDependencies": {
"@types/apicache": "^1.2.0",
@ -180,10 +180,17 @@
"@types/validator": "^12.0.1",
"@types/webtorrent": "^0.107.0",
"@types/ws": "^7.2.1",
"@typescript-eslint/eslint-plugin": "^2.18.0",
"chai": "^4.1.1",
"chai-json-schema": "^1.5.0",
"chai-xml": "^0.3.2",
"concurrently": "^5.0.0",
"eslint": "^6.8.0",
"eslint-config-standard-with-typescript": "^12.0.1",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"libxmljs": "0.19.7",
"maildev": "^1.0.0-rc3",
"marked": "^0.8.0",
@ -195,8 +202,6 @@
"supertest": "^4.0.2",
"swagger-cli": "^3.0.1",
"ts-node": "8.6.2",
"tslint": "^6.0.0",
"tslint-config-standard": "^9.0.0",
"typescript": "^3.7.2"
},
"scripty": {

View File

@ -35,7 +35,7 @@ elif [ "$1" = "api-4" ]; then
npm run build:server
sh ./server/tests/api/ci-4.sh 2
elif [ "$1" = "lint" ]; then
npm run tslint -- --project ./tsconfig.json -c ./tslint.json server.ts "server/**/*.ts" "shared/**/*.ts"
npm run eslint -- --ext .ts "server/**/*.ts" "shared/**/*.ts"
npm run swagger-cli -- validate support/doc/api/openapi.yaml
( cd client

View File

@ -38,6 +38,6 @@ async function run () {
}
await JobQueue.Instance.init()
await JobQueue.Instance.createJob({ type: 'video-file-import', payload: dataInput })
await JobQueue.Instance.createJobWithPromise({ type: 'video-file-import', payload: dataInput })
console.log('Import job for video %s created.', video.uuid)
}

View File

@ -72,7 +72,7 @@ async function run () {
await JobQueue.Instance.init()
for (const d of dataInput) {
await JobQueue.Instance.createJob({ type: 'video-transcoding', payload: d })
await JobQueue.Instance.createJobWithPromise({ type: 'video-transcoding', payload: d })
console.log('Transcoding job for video %s created.', video.uuid)
}
}

View File

@ -122,7 +122,7 @@ activityPubClientRouter.get('/videos/watch/:videoId/comments/:commentId/activity
activityPubClientRouter.get('/video-channels/:name',
executeIfActivityPub,
asyncMiddleware(localVideoChannelValidator),
asyncMiddleware(videoChannelController)
videoChannelController
)
activityPubClientRouter.get('/video-channels/:name/followers',
executeIfActivityPub,
@ -154,7 +154,7 @@ activityPubClientRouter.get('/video-playlists/:playlistId',
activityPubClientRouter.get('/video-playlists/:playlistId/:videoId',
executeIfActivityPub,
asyncMiddleware(videoPlaylistElementAPGetValidator),
asyncMiddleware(videoPlaylistElementController)
videoPlaylistElementController
)
// ---------------------------------------------------------------------------
@ -281,7 +281,7 @@ async function videoCommentsController (req: express.Request, res: express.Respo
return activityPubResponse(activityPubContextify(json), res)
}
async function videoChannelController (req: express.Request, res: express.Response) {
function videoChannelController (req: express.Request, res: express.Response) {
const videoChannel = res.locals.videoChannel
return activityPubResponse(activityPubContextify(videoChannel.toActivityPubObject()), res)
@ -353,7 +353,7 @@ async function videoPlaylistController (req: express.Request, res: express.Respo
return activityPubResponse(activityPubContextify(object), res)
}
async function videoPlaylistElementController (req: express.Request, res: express.Response) {
function videoPlaylistElementController (req: express.Request, res: express.Response) {
const videoPlaylistElement = res.locals.videoPlaylistElementAP
const json = videoPlaylistElement.toActivityPubObject()

View File

@ -46,6 +46,10 @@ const inboxQueue = queue<QueueParam, Error>((task, cb) => {
processActivities(task.activities, options)
.then(() => cb())
.catch(err => {
logger.error('Error in process activities.', { err })
cb()
})
})
function inboxController (req: express.Request, res: express.Response) {

View File

@ -16,21 +16,17 @@ import {
accountNameWithHostGetValidator,
accountsSortValidator,
ensureAuthUserOwnsAccountValidator,
videosSortValidator,
videoChannelsSortValidator
videoChannelsSortValidator,
videosSortValidator
} from '../../middlewares/validators'
import { AccountModel } from '../../models/account/account'
import { AccountVideoRateModel } from '../../models/account/account-video-rate'
import { VideoModel } from '../../models/video/video'
import { buildNSFWFilter, isUserAbleToSearchRemoteURI, getCountVideos } from '../../helpers/express-utils'
import { buildNSFWFilter, getCountVideos, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils'
import { VideoChannelModel } from '../../models/video/video-channel'
import { JobQueue } from '../../lib/job-queue'
import { logger } from '../../helpers/logger'
import { VideoPlaylistModel } from '../../models/video/video-playlist'
import {
commonVideoPlaylistFiltersValidator,
videoPlaylistsSearchValidator
} from '../../middlewares/validators/videos/video-playlists'
import { commonVideoPlaylistFiltersValidator, videoPlaylistsSearchValidator } from '../../middlewares/validators/videos/video-playlists'
const accountsRouter = express.Router()
@ -104,7 +100,6 @@ function getAccount (req: express.Request, res: express.Response) {
if (account.isOutdated()) {
JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'actor', url: account.Actor.url } })
.catch(err => logger.error('Cannot create AP refresher job for actor %s.', account.Actor.url, { err }))
}
return res.json(account.toFormattedJSON())

View File

@ -31,12 +31,12 @@ configRouter.get('/',
configRouter.get('/custom',
authenticate,
ensureUserHasRight(UserRight.MANAGE_CONFIGURATION),
asyncMiddleware(getCustomConfig)
getCustomConfig
)
configRouter.put('/custom',
authenticate,
ensureUserHasRight(UserRight.MANAGE_CONFIGURATION),
asyncMiddleware(customConfigUpdateValidator),
customConfigUpdateValidator,
asyncMiddleware(updateCustomConfig)
)
configRouter.delete('/custom',
@ -196,7 +196,7 @@ function getAbout (req: express.Request, res: express.Response) {
return res.json(about).end()
}
async function getCustomConfig (req: express.Request, res: express.Response) {
function getCustomConfig (req: express.Request, res: express.Response) {
const data = customConfig()
return res.json(data).end()
@ -250,7 +250,7 @@ function getRegisteredThemes () {
function getEnabledResolutions () {
return Object.keys(CONFIG.TRANSCODING.RESOLUTIONS)
.filter(key => CONFIG.TRANSCODING.ENABLED && CONFIG.TRANSCODING.RESOLUTIONS[ key ] === true)
.filter(key => CONFIG.TRANSCODING.ENABLED && CONFIG.TRANSCODING.RESOLUTIONS[key] === true)
.map(r => parseInt(r, 10))
}
@ -340,13 +340,13 @@ function customConfig (): CustomConfig {
allowAudioFiles: CONFIG.TRANSCODING.ALLOW_AUDIO_FILES,
threads: CONFIG.TRANSCODING.THREADS,
resolutions: {
'0p': CONFIG.TRANSCODING.RESOLUTIONS[ '0p' ],
'240p': CONFIG.TRANSCODING.RESOLUTIONS[ '240p' ],
'360p': CONFIG.TRANSCODING.RESOLUTIONS[ '360p' ],
'480p': CONFIG.TRANSCODING.RESOLUTIONS[ '480p' ],
'720p': CONFIG.TRANSCODING.RESOLUTIONS[ '720p' ],
'1080p': CONFIG.TRANSCODING.RESOLUTIONS[ '1080p' ],
'2160p': CONFIG.TRANSCODING.RESOLUTIONS[ '2160p' ]
'0p': CONFIG.TRANSCODING.RESOLUTIONS['0p'],
'240p': CONFIG.TRANSCODING.RESOLUTIONS['240p'],
'360p': CONFIG.TRANSCODING.RESOLUTIONS['360p'],
'480p': CONFIG.TRANSCODING.RESOLUTIONS['480p'],
'720p': CONFIG.TRANSCODING.RESOLUTIONS['720p'],
'1080p': CONFIG.TRANSCODING.RESOLUTIONS['1080p'],
'2160p': CONFIG.TRANSCODING.RESOLUTIONS['2160p']
},
webtorrent: {
enabled: CONFIG.TRANSCODING.WEBTORRENT.ENABLED

View File

@ -50,7 +50,7 @@ async function listJobs (req: express.Request, res: express.Response) {
})
const total = await JobQueue.Instance.count(state)
const result: ResultList<any> = {
const result: ResultList<Job> = {
total,
data: jobs.map(j => formatJob(j, state))
}

View File

@ -24,7 +24,7 @@ export { overviewsRouter }
const buildSamples = memoizee(async function () {
const [ categories, channels, tags ] = await Promise.all([
VideoModel.getRandomFieldSamples('category', OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT),
VideoModel.getRandomFieldSamples('channelId', OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD ,OVERVIEWS.VIDEOS.SAMPLES_COUNT),
VideoModel.getRandomFieldSamples('channelId', OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT),
TagModel.getRandomSamples(OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT)
])

View File

@ -1,13 +1,13 @@
import * as express from 'express'
import { UserRight } from '../../../../shared/models/users'
import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../../middlewares'
import { authenticate, ensureUserHasRight } from '../../../middlewares'
const debugRouter = express.Router()
debugRouter.get('/debug',
authenticate,
ensureUserHasRight(UserRight.MANAGE_DEBUG),
asyncMiddleware(getDebug)
getDebug
)
// ---------------------------------------------------------------------------
@ -18,7 +18,7 @@ export {
// ---------------------------------------------------------------------------
async function getDebug (req: express.Request, res: express.Response) {
function getDebug (req: express.Request, res: express.Response) {
return res.json({
ip: req.ip
}).end()

View File

@ -135,7 +135,6 @@ async function followInstance (req: express.Request, res: express.Response) {
}
JobQueue.Instance.createJob({ type: 'activitypub-follow', payload })
.catch(err => logger.error('Cannot create follow job for %s.', host, err))
}
return res.status(204).end()

View File

@ -59,9 +59,9 @@ async function getLogs (req: express.Request, res: express.Response) {
}
async function generateOutput (options: {
startDateQuery: string,
endDateQuery?: string,
level: LogLevel,
startDateQuery: string
endDateQuery?: string
level: LogLevel
nameFilter: RegExp
}) {
const { startDateQuery, level, nameFilter } = options
@ -111,7 +111,7 @@ async function getOutputFromFile (path: string, startDate: Date, endDate: Date,
const output: any[] = []
for (let i = lines.length - 1; i >= 0; i--) {
const line = lines[ i ]
const line = lines[i]
let log: any
try {
@ -122,7 +122,7 @@ async function getOutputFromFile (path: string, startDate: Date, endDate: Date,
}
logTime = new Date(log.timestamp).getTime()
if (logTime >= startTime && logTime <= endTime && logsLevel[ log.level ] >= logsLevel[ level ]) {
if (logTime >= startTime && logTime <= endTime && logsLevel[log.level] >= logsLevel[level]) {
output.push(log)
currentSize += line.length

View File

@ -84,7 +84,7 @@ async function addVideoRedundancy (req: express.Request, res: express.Response)
videoId: res.locals.onlyVideo.id
}
await JobQueue.Instance.createJob({
await JobQueue.Instance.createJobWithPromise({
type: 'video-redundancy',
payload
})

View File

@ -39,7 +39,7 @@ meRouter.get('/me',
)
meRouter.delete('/me',
authenticate,
asyncMiddleware(deleteMeValidator),
deleteMeValidator,
asyncMiddleware(deleteMe)
)
@ -214,7 +214,7 @@ async function updateMe (req: express.Request, res: express.Response) {
}
async function updateMyAvatar (req: express.Request, res: express.Response) {
const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ]
const avatarPhysicalFile = req.files['avatarfile'][0]
const user = res.locals.oauth.token.user
const userAccount = await AccountModel.load(user.Account.id)

View File

@ -19,7 +19,6 @@ import { buildNSFWFilter, getCountVideos } from '../../../helpers/express-utils'
import { VideoFilter } from '../../../../shared/models/videos/video-query.type'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
import { JobQueue } from '../../../lib/job-queue'
import { logger } from '../../../helpers/logger'
import { sequelizeTypescript } from '../../../initializers/database'
const mySubscriptionsRouter = express.Router()
@ -52,7 +51,7 @@ mySubscriptionsRouter.get('/me/subscriptions',
mySubscriptionsRouter.post('/me/subscriptions',
authenticate,
userSubscriptionAddValidator,
asyncMiddleware(addUserSubscription)
addUserSubscription
)
mySubscriptionsRouter.get('/me/subscriptions/:uri',
@ -106,7 +105,7 @@ async function areSubscriptionsExist (req: express.Request, res: express.Respons
return res.json(existObject)
}
async function addUserSubscription (req: express.Request, res: express.Response) {
function addUserSubscription (req: express.Request, res: express.Response) {
const user = res.locals.oauth.token.User
const [ name, host ] = req.body.uri.split('@')
@ -117,7 +116,6 @@ async function addUserSubscription (req: express.Request, res: express.Response)
}
JobQueue.Instance.createJob({ type: 'activitypub-follow', payload })
.catch(err => logger.error('Cannot create follow job for subscription %s.', req.body.uri, err))
return res.status(204).end()
}

View File

@ -119,7 +119,7 @@ async function listVideoChannels (req: express.Request, res: express.Response) {
}
async function updateVideoChannelAvatar (req: express.Request, res: express.Response) {
const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ]
const avatarPhysicalFile = req.files['avatarfile'][0]
const videoChannel = res.locals.videoChannel
const oldVideoChannelAuditKeys = new VideoChannelAuditView(videoChannel.toFormattedJSON())
@ -232,7 +232,6 @@ async function getVideoChannel (req: express.Request, res: express.Response) {
if (videoChannelWithVideos.isOutdated()) {
JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'actor', url: videoChannelWithVideos.Actor.url } })
.catch(err => logger.error('Cannot create AP refresher job for actor %s.', videoChannelWithVideos.Actor.url, { err }))
}
return res.json(videoChannelWithVideos.toFormattedJSON())

View File

@ -144,7 +144,6 @@ function getVideoPlaylist (req: express.Request, res: express.Response) {
if (videoPlaylist.isOutdated()) {
JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video-playlist', url: videoPlaylist.url } })
.catch(err => logger.error('Cannot create AP refresher job for playlist %s.', videoPlaylist.url, { err }))
}
return res.json(videoPlaylist.toFormattedJSON())

View File

@ -88,12 +88,12 @@ async function addTorrentImport (req: express.Request, res: express.Response, to
const buf = await readFile(torrentfile.path)
const parsedTorrent = parseTorrent(buf)
videoName = isArray(parsedTorrent.name) ? parsedTorrent.name[ 0 ] : parsedTorrent.name as string
videoName = isArray(parsedTorrent.name) ? parsedTorrent.name[0] : parsedTorrent.name as string
} else {
magnetUri = body.magnetUri
const parsed = magnetUtil.decode(magnetUri)
videoName = isArray(parsed.name) ? parsed.name[ 0 ] : parsed.name as string
videoName = isArray(parsed.name) ? parsed.name[0] : parsed.name as string
}
const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName })
@ -124,7 +124,7 @@ async function addTorrentImport (req: express.Request, res: express.Response, to
videoImportId: videoImport.id,
magnetUri
}
await JobQueue.Instance.createJob({ type: 'video-import', payload })
await JobQueue.Instance.createJobWithPromise({ type: 'video-import', payload })
auditLogger.create(getAuditIdFromRes(res), new VideoImportAuditView(videoImport.toFormattedJSON()))
@ -176,7 +176,7 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response)
downloadThumbnail: !thumbnailModel,
downloadPreview: !previewModel
}
await JobQueue.Instance.createJob({ type: 'video-import', payload })
await JobQueue.Instance.createJobWithPromise({ type: 'video-import', payload })
auditLogger.create(getAuditIdFromRes(res), new VideoImportAuditView(videoImport.toFormattedJSON()))
@ -211,7 +211,7 @@ function buildVideo (channelId: number, body: VideoImportCreate, importData: You
async function processThumbnail (req: express.Request, video: VideoModel) {
const thumbnailField = req.files ? req.files['thumbnailfile'] : undefined
if (thumbnailField) {
const thumbnailPhysicalFile = thumbnailField[ 0 ]
const thumbnailPhysicalFile = thumbnailField[0]
return createVideoMiniatureFromExisting(thumbnailPhysicalFile.path, video, ThumbnailType.MINIATURE, false)
}
@ -231,12 +231,12 @@ async function processPreview (req: express.Request, video: VideoModel) {
}
function insertIntoDB (parameters: {
video: MVideoThumbnailAccountDefault,
thumbnailModel: MThumbnail,
previewModel: MThumbnail,
videoChannel: MChannelAccountDefault,
tags: string[],
videoImportAttributes: Partial<MVideoImport>,
video: MVideoThumbnailAccountDefault
thumbnailModel: MThumbnail
previewModel: MThumbnail
videoChannel: MChannelAccountDefault
tags: string[]
videoImportAttributes: Partial<MVideoImport>
user: MUser
}): Bluebird<MVideoImportFormattable> {
const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters

View File

@ -12,8 +12,7 @@ import {
VIDEO_CATEGORIES,
VIDEO_LANGUAGES,
VIDEO_LICENCES,
VIDEO_PRIVACIES,
VIDEO_TRANSCODING_FPS
VIDEO_PRIVACIES
} from '../../../initializers/constants'
import {
changeVideoChannelShare,
@ -308,7 +307,7 @@ async function addVideo (req: express.Request, res: express.Response) {
}
}
await JobQueue.Instance.createJob({ type: 'video-transcoding', payload: dataInput })
await JobQueue.Instance.createJobWithPromise({ type: 'video-transcoding', payload: dataInput })
}
Hooks.runAction('action:api.video.uploaded', { video: videoCreated })
@ -453,7 +452,6 @@ async function getVideo (req: express.Request, res: express.Response) {
if (video.isOutdated()) {
JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video', url: video.url } })
.catch(err => logger.error('Cannot create AP refresher job for video %s.', video.url, { err }))
}
return res.json(video.toFormattedDetailsJSON())

View File

@ -66,7 +66,7 @@ export {
// ---------------------------------------------------------------------------
async function serveServerTranslations (req: express.Request, res: express.Response) {
function serveServerTranslations (req: express.Request, res: express.Response) {
const locale = req.params.locale
const file = req.params.file

View File

@ -45,12 +45,12 @@ staticRouter.use(
staticRouter.use(
STATIC_DOWNLOAD_PATHS.TORRENTS + ':id-:resolution([0-9]+).torrent',
asyncMiddleware(videosDownloadValidator),
asyncMiddleware(downloadTorrent)
downloadTorrent
)
staticRouter.use(
STATIC_DOWNLOAD_PATHS.TORRENTS + ':id-:resolution([0-9]+)-hls.torrent',
asyncMiddleware(videosDownloadValidator),
asyncMiddleware(downloadHLSVideoFileTorrent)
downloadHLSVideoFileTorrent
)
// Videos path for webseeding
@ -68,13 +68,13 @@ staticRouter.use(
staticRouter.use(
STATIC_DOWNLOAD_PATHS.VIDEOS + ':id-:resolution([0-9]+).:extension',
asyncMiddleware(videosDownloadValidator),
asyncMiddleware(downloadVideoFile)
downloadVideoFile
)
staticRouter.use(
STATIC_DOWNLOAD_PATHS.HLS_VIDEOS + ':id-:resolution([0-9]+)-fragmented.:extension',
asyncMiddleware(videosDownloadValidator),
asyncMiddleware(downloadHLSVideoFile)
downloadHLSVideoFile
)
// HLS
@ -325,7 +325,7 @@ async function generateNodeinfo (req: express.Request, res: express.Response) {
return res.send(json).end()
}
async function downloadTorrent (req: express.Request, res: express.Response) {
function downloadTorrent (req: express.Request, res: express.Response) {
const video = res.locals.videoAll
const videoFile = getVideoFile(req, video.VideoFiles)
@ -334,7 +334,7 @@ async function downloadTorrent (req: express.Request, res: express.Response) {
return res.download(getTorrentFilePath(video, videoFile), `${video.name}-${videoFile.resolution}p.torrent`)
}
async function downloadHLSVideoFileTorrent (req: express.Request, res: express.Response) {
function downloadHLSVideoFileTorrent (req: express.Request, res: express.Response) {
const video = res.locals.videoAll
const playlist = getHLSPlaylist(video)
@ -346,7 +346,7 @@ async function downloadHLSVideoFileTorrent (req: express.Request, res: express.R
return res.download(getTorrentFilePath(playlist, videoFile), `${video.name}-${videoFile.resolution}p-hls.torrent`)
}
async function downloadVideoFile (req: express.Request, res: express.Response) {
function downloadVideoFile (req: express.Request, res: express.Response) {
const video = res.locals.videoAll
const videoFile = getVideoFile(req, video.VideoFiles)
@ -355,7 +355,7 @@ async function downloadVideoFile (req: express.Request, res: express.Response) {
return res.download(getVideoFilePath(video, videoFile), `${video.name}-${videoFile.resolution}p${videoFile.extname}`)
}
async function downloadHLSVideoFile (req: express.Request, res: express.Response) {
function downloadHLSVideoFile (req: express.Request, res: express.Response) {
const video = res.locals.videoAll
const playlist = getHLSPlaylist(video)
if (!playlist) return res.status(404).end

View File

@ -6,7 +6,6 @@ import * as proxyAddr from 'proxy-addr'
import { Server as WebSocketServer } from 'ws'
import { TRACKER_RATE_LIMITS } from '../initializers/constants'
import { VideoFileModel } from '../models/video/video-file'
import { parse } from 'url'
import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-playlist'
import { CONFIG } from '../initializers/config'
@ -38,11 +37,11 @@ const trackerServer = new TrackerServer({
const key = ip + '-' + infoHash
peersIps[ ip ] = peersIps[ ip ] ? peersIps[ ip ] + 1 : 1
peersIpInfoHash[ key ] = peersIpInfoHash[ key ] ? peersIpInfoHash[ key ] + 1 : 1
peersIps[ip] = peersIps[ip] ? peersIps[ip] + 1 : 1
peersIpInfoHash[key] = peersIpInfoHash[key] ? peersIpInfoHash[key] + 1 : 1
if (CONFIG.TRACKER.REJECT_TOO_MANY_ANNOUNCES && peersIpInfoHash[ key ] > TRACKER_RATE_LIMITS.ANNOUNCES_PER_IP_PER_INFOHASH) {
return cb(new Error(`Too many requests (${peersIpInfoHash[ key ]} of ip ${ip} for torrent ${infoHash}`))
if (CONFIG.TRACKER.REJECT_TOO_MANY_ANNOUNCES && peersIpInfoHash[key] > TRACKER_RATE_LIMITS.ANNOUNCES_PER_IP_PER_INFOHASH) {
return cb(new Error(`Too many requests (${peersIpInfoHash[key]} of ip ${ip} for torrent ${infoHash}`))
}
try {
@ -87,10 +86,8 @@ function createWebsocketTrackerServer (app: express.Application) {
trackerServer.onWebSocketConnection(ws)
})
server.on('upgrade', (request, socket, head) => {
const pathname = parse(request.url).pathname
if (pathname === '/tracker/socket') {
server.on('upgrade', (request: express.Request, socket, head) => {
if (request.path === '/tracker/socket') {
wss.handleUpgrade(request, socket, head, ws => wss.emit('connection', ws, request))
}

View File

@ -5,7 +5,7 @@ import { Activity } from '../../shared/models/activitypub'
import { ACTIVITY_PUB, REMOTE_SCHEME } from '../initializers/constants'
import { signJsonLDObject } from './peertube-crypto'
import { pageToStartAndCount } from './core-utils'
import { parse } from 'url'
import { URL } from 'url'
import { MActor, MVideoAccountLight } from '../typings/models'
function activityPubContextify <T> (data: T) {
@ -161,8 +161,8 @@ function getAPId (activity: string | { id: string }) {
}
function checkUrlsSameHost (url1: string, url2: string) {
const idHost = parse(url1).host
const actorHost = parse(url2).host
const idHost = new URL(url1).host
const actorHost = new URL(url2).host
return idHost && actorHost && idHost.toLowerCase() === actorHost.toLowerCase()
}

View File

@ -81,7 +81,8 @@ function auditLoggerFactory (domain: string) {
}
abstract class EntityAuditView {
constructor (private keysToKeep: Array<string>, private prefix: string, private entityInfos: object) { }
constructor (private readonly keysToKeep: string[], private readonly prefix: string, private readonly entityInfos: object) { }
toLogKeys (): object {
return chain(flatten(this.entityInfos, { delimiter: '-', safe: true }))
.pick(this.keysToKeep)
@ -121,7 +122,7 @@ const videoKeysToKeep = [
'downloadEnabled'
]
class VideoAuditView extends EntityAuditView {
constructor (private video: VideoDetails) {
constructor (private readonly video: VideoDetails) {
super(videoKeysToKeep, 'video', video)
}
}
@ -132,7 +133,7 @@ const videoImportKeysToKeep = [
'video-name'
]
class VideoImportAuditView extends EntityAuditView {
constructor (private videoImport: VideoImport) {
constructor (private readonly videoImport: VideoImport) {
super(videoImportKeysToKeep, 'video-import', videoImport)
}
}
@ -151,7 +152,7 @@ const commentKeysToKeep = [
'account-name'
]
class CommentAuditView extends EntityAuditView {
constructor (private comment: VideoComment) {
constructor (private readonly comment: VideoComment) {
super(commentKeysToKeep, 'comment', comment)
}
}
@ -180,7 +181,7 @@ const userKeysToKeep = [
'videoChannels'
]
class UserAuditView extends EntityAuditView {
constructor (private user: User) {
constructor (private readonly user: User) {
super(userKeysToKeep, 'user', user)
}
}
@ -206,7 +207,7 @@ const channelKeysToKeep = [
'ownerAccount-displayedName'
]
class VideoChannelAuditView extends EntityAuditView {
constructor (private channel: VideoChannel) {
constructor (private readonly channel: VideoChannel) {
super(channelKeysToKeep, 'channel', channel)
}
}
@ -221,7 +222,7 @@ const videoAbuseKeysToKeep = [
'createdAt'
]
class VideoAbuseAuditView extends EntityAuditView {
constructor (private videoAbuse: VideoAbuse) {
constructor (private readonly videoAbuse: VideoAbuse) {
super(videoAbuseKeysToKeep, 'abuse', videoAbuse)
}
}
@ -253,9 +254,12 @@ class CustomConfigAuditView extends EntityAuditView {
const infos: any = customConfig
const resolutionsDict = infos.transcoding.resolutions
const resolutionsArray = []
Object.entries(resolutionsDict).forEach(([resolution, isEnabled]) => {
if (isEnabled) resolutionsArray.push(resolution)
})
Object.entries(resolutionsDict)
.forEach(([ resolution, isEnabled ]) => {
if (isEnabled) resolutionsArray.push(resolution)
})
Object.assign({}, infos, { transcoding: { resolutions: resolutionsArray } })
super(customConfigKeysToKeep, 'config', infos)
}

View File

@ -1,9 +1,11 @@
/* eslint-disable no-useless-call */
/*
Different from 'utils' because we don't not import other PeerTube modules.
Useful to avoid circular dependencies.
*/
import { createHash, HexBase64Latin1Encoding, pseudoRandomBytes } from 'crypto'
import { createHash, HexBase64Latin1Encoding, randomBytes } from 'crypto'
import { basename, isAbsolute, join, resolve } from 'path'
import * as pem from 'pem'
import { URL } from 'url'
@ -22,31 +24,31 @@ const objectConverter = (oldObject: any, keyConverter: (e: string) => string, va
const newObject = {}
Object.keys(oldObject).forEach(oldKey => {
const newKey = keyConverter(oldKey)
newObject[ newKey ] = objectConverter(oldObject[ oldKey ], keyConverter, valueConverter)
newObject[newKey] = objectConverter(oldObject[oldKey], keyConverter, valueConverter)
})
return newObject
}
const timeTable = {
ms: 1,
second: 1000,
minute: 60000,
hour: 3600000,
day: 3600000 * 24,
week: 3600000 * 24 * 7,
month: 3600000 * 24 * 30
ms: 1,
second: 1000,
minute: 60000,
hour: 3600000,
day: 3600000 * 24,
week: 3600000 * 24 * 7,
month: 3600000 * 24 * 30
}
export function parseDurationToMs (duration: number | string): number {
if (typeof duration === 'number') return duration
if (typeof duration === 'string') {
const split = duration.match(/^([\d\.,]+)\s?(\w+)$/)
const split = duration.match(/^([\d.,]+)\s?(\w+)$/)
if (split.length === 3) {
const len = parseFloat(split[1])
let unit = split[2].replace(/s$/i,'').toLowerCase()
let unit = split[2].replace(/s$/i, '').toLowerCase()
if (unit === 'm') {
unit = 'ms'
}
@ -73,21 +75,21 @@ export function parseBytes (value: string | number): number {
if (value.match(tgm)) {
match = value.match(tgm)
return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024
+ parseInt(match[2], 10) * 1024 * 1024 * 1024
+ parseInt(match[3], 10) * 1024 * 1024
return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024 +
parseInt(match[2], 10) * 1024 * 1024 * 1024 +
parseInt(match[3], 10) * 1024 * 1024
} else if (value.match(tg)) {
match = value.match(tg)
return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024
+ parseInt(match[2], 10) * 1024 * 1024 * 1024
return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024 +
parseInt(match[2], 10) * 1024 * 1024 * 1024
} else if (value.match(tm)) {
match = value.match(tm)
return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024
+ parseInt(match[2], 10) * 1024 * 1024
return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024 +
parseInt(match[2], 10) * 1024 * 1024
} else if (value.match(gm)) {
match = value.match(gm)
return parseInt(match[1], 10) * 1024 * 1024 * 1024
+ parseInt(match[2], 10) * 1024 * 1024
return parseInt(match[1], 10) * 1024 * 1024 * 1024 +
parseInt(match[2], 10) * 1024 * 1024
} else if (value.match(t)) {
match = value.match(t)
return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024
@ -137,6 +139,7 @@ function getAppNumber () {
}
let rootPath: string
function root () {
if (rootPath) return rootPath
@ -163,7 +166,7 @@ function escapeHTML (stringParam) {
'=': '&#x3D;'
}
return String(stringParam).replace(/[&<>"'`=\/]/g, s => entityMap[s])
return String(stringParam).replace(/[&<>"'`=/]/g, s => entityMap[s])
}
function pageToStartAndCount (page: number, itemsPerPage: number) {
@ -202,6 +205,7 @@ function sha1 (str: string | Buffer, encoding: HexBase64Latin1Encoding = 'hex')
function execShell (command: string, options?: ExecOptions) {
return new Promise<{ err?: Error, stdout: string, stderr: string }>((res, rej) => {
exec(command, options, (err, stdout, stderr) => {
// eslint-disable-next-line prefer-promise-reject-errors
if (err) return rej({ err, stdout, stderr })
return res({ stdout, stderr })
@ -226,14 +230,6 @@ function promisify1<T, A> (func: (arg: T, cb: (err: any, result: A) => void) =>
}
}
function promisify1WithVoid<T> (func: (arg: T, cb: (err: any) => void) => void): (arg: T) => Promise<void> {
return function promisified (arg: T): Promise<void> {
return new Promise<void>((resolve: () => void, reject: (err: any) => void) => {
func.apply(null, [ arg, (err: any) => err ? reject(err) : resolve() ])
})
}
}
function promisify2<T, U, A> (func: (arg1: T, arg2: U, cb: (err: any, result: A) => void) => void): (arg1: T, arg2: U) => Promise<A> {
return function promisified (arg1: T, arg2: U): Promise<A> {
return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => {
@ -242,15 +238,7 @@ function promisify2<T, U, A> (func: (arg1: T, arg2: U, cb: (err: any, result: A)
}
}
function promisify2WithVoid<T, U> (func: (arg1: T, arg2: U, cb: (err: any) => void) => void): (arg1: T, arg2: U) => Promise<void> {
return function promisified (arg1: T, arg2: U): Promise<void> {
return new Promise<void>((resolve: () => void, reject: (err: any) => void) => {
func.apply(null, [ arg1, arg2, (err: any) => err ? reject(err) : resolve() ])
})
}
}
const pseudoRandomBytesPromise = promisify1<number, Buffer>(pseudoRandomBytes)
const randomBytesPromise = promisify1<number, Buffer>(randomBytes)
const createPrivateKey = promisify1<number, { key: string }>(pem.createPrivateKey)
const getPublicKey = promisify1<string, { publicKey: string }>(pem.getPublicKey)
const execPromise2 = promisify2<string, any, string>(exec)
@ -280,7 +268,7 @@ export {
promisify1,
promisify2,
pseudoRandomBytesPromise,
randomBytesPromise,
createPrivateKey,
getPublicKey,
execPromise2,

View File

@ -5,52 +5,52 @@ import { logger } from './logger'
const CACHE = {
'https://w3id.org/security/v1': {
'@context': {
'id': '@id',
'type': '@type',
id: '@id',
type: '@type',
'dc': 'http://purl.org/dc/terms/',
'sec': 'https://w3id.org/security#',
'xsd': 'http://www.w3.org/2001/XMLSchema#',
dc: 'http://purl.org/dc/terms/',
sec: 'https://w3id.org/security#',
xsd: 'http://www.w3.org/2001/XMLSchema#',
'EcdsaKoblitzSignature2016': 'sec:EcdsaKoblitzSignature2016',
'Ed25519Signature2018': 'sec:Ed25519Signature2018',
'EncryptedMessage': 'sec:EncryptedMessage',
'GraphSignature2012': 'sec:GraphSignature2012',
'LinkedDataSignature2015': 'sec:LinkedDataSignature2015',
'LinkedDataSignature2016': 'sec:LinkedDataSignature2016',
'CryptographicKey': 'sec:Key',
EcdsaKoblitzSignature2016: 'sec:EcdsaKoblitzSignature2016',
Ed25519Signature2018: 'sec:Ed25519Signature2018',
EncryptedMessage: 'sec:EncryptedMessage',
GraphSignature2012: 'sec:GraphSignature2012',
LinkedDataSignature2015: 'sec:LinkedDataSignature2015',
LinkedDataSignature2016: 'sec:LinkedDataSignature2016',
CryptographicKey: 'sec:Key',
'authenticationTag': 'sec:authenticationTag',
'canonicalizationAlgorithm': 'sec:canonicalizationAlgorithm',
'cipherAlgorithm': 'sec:cipherAlgorithm',
'cipherData': 'sec:cipherData',
'cipherKey': 'sec:cipherKey',
'created': { '@id': 'dc:created', '@type': 'xsd:dateTime' },
'creator': { '@id': 'dc:creator', '@type': '@id' },
'digestAlgorithm': 'sec:digestAlgorithm',
'digestValue': 'sec:digestValue',
'domain': 'sec:domain',
'encryptionKey': 'sec:encryptionKey',
'expiration': { '@id': 'sec:expiration', '@type': 'xsd:dateTime' },
'expires': { '@id': 'sec:expiration', '@type': 'xsd:dateTime' },
'initializationVector': 'sec:initializationVector',
'iterationCount': 'sec:iterationCount',
'nonce': 'sec:nonce',
'normalizationAlgorithm': 'sec:normalizationAlgorithm',
'owner': { '@id': 'sec:owner', '@type': '@id' },
'password': 'sec:password',
'privateKey': { '@id': 'sec:privateKey', '@type': '@id' },
'privateKeyPem': 'sec:privateKeyPem',
'publicKey': { '@id': 'sec:publicKey', '@type': '@id' },
'publicKeyBase58': 'sec:publicKeyBase58',
'publicKeyPem': 'sec:publicKeyPem',
'publicKeyWif': 'sec:publicKeyWif',
'publicKeyService': { '@id': 'sec:publicKeyService', '@type': '@id' },
'revoked': { '@id': 'sec:revoked', '@type': 'xsd:dateTime' },
'salt': 'sec:salt',
'signature': 'sec:signature',
'signatureAlgorithm': 'sec:signingAlgorithm',
'signatureValue': 'sec:signatureValue'
authenticationTag: 'sec:authenticationTag',
canonicalizationAlgorithm: 'sec:canonicalizationAlgorithm',
cipherAlgorithm: 'sec:cipherAlgorithm',
cipherData: 'sec:cipherData',
cipherKey: 'sec:cipherKey',
created: { '@id': 'dc:created', '@type': 'xsd:dateTime' },
creator: { '@id': 'dc:creator', '@type': '@id' },
digestAlgorithm: 'sec:digestAlgorithm',
digestValue: 'sec:digestValue',
domain: 'sec:domain',
encryptionKey: 'sec:encryptionKey',
expiration: { '@id': 'sec:expiration', '@type': 'xsd:dateTime' },
expires: { '@id': 'sec:expiration', '@type': 'xsd:dateTime' },
initializationVector: 'sec:initializationVector',
iterationCount: 'sec:iterationCount',
nonce: 'sec:nonce',
normalizationAlgorithm: 'sec:normalizationAlgorithm',
owner: { '@id': 'sec:owner', '@type': '@id' },
password: 'sec:password',
privateKey: { '@id': 'sec:privateKey', '@type': '@id' },
privateKeyPem: 'sec:privateKeyPem',
publicKey: { '@id': 'sec:publicKey', '@type': '@id' },
publicKeyBase58: 'sec:publicKeyBase58',
publicKeyPem: 'sec:publicKeyPem',
publicKeyWif: 'sec:publicKeyWif',
publicKeyService: { '@id': 'sec:publicKeyService', '@type': '@id' },
revoked: { '@id': 'sec:revoked', '@type': 'xsd:dateTime' },
salt: 'sec:salt',
signature: 'sec:signature',
signatureAlgorithm: 'sec:signingAlgorithm',
signatureValue: 'sec:signatureValue'
}
}
}
@ -60,12 +60,12 @@ const nodeDocumentLoader = jsonld.documentLoaders.node()
const lru = new AsyncLRU({
max: 10,
load: (url, cb) => {
if (CACHE[ url ] !== undefined) {
if (CACHE[url] !== undefined) {
logger.debug('Using cache for JSON-LD %s.', url)
return cb(null, {
contextUrl: null,
document: CACHE[ url ],
document: CACHE[url],
documentUrl: url
})
}

View File

@ -6,7 +6,7 @@ import { isHostValid } from '../servers'
import { peertubeTruncate } from '@server/helpers/core-utils'
function isActorEndpointsObjectValid (endpointObject: any) {
if (endpointObject && endpointObject.sharedInbox) {
if (endpointObject?.sharedInbox) {
return isActivityPubUrlValid(endpointObject.sharedInbox)
}
@ -101,8 +101,6 @@ function normalizeActor (actor: any) {
actor.summary = null
}
}
return
}
function isValidActorHandle (handle: string) {

View File

@ -48,8 +48,6 @@ function normalizeComment (comment: any) {
if (typeof comment.url === 'object') comment.url = comment.url.href || comment.url.url
else comment.url = comment.id
}
return
}
function isCommentTypeValid (comment: any): boolean {

View File

@ -94,13 +94,13 @@ function isFileValid (
if (isArray(files)) return optional
// Should have a file
const fileArray = files[ field ]
const fileArray = files[field]
if (!fileArray || fileArray.length === 0) {
return optional
}
// The file should exist
const file = fileArray[ 0 ]
const file = fileArray[0]
if (!file || !file.originalname) return false
// Check size

View File

@ -14,7 +14,7 @@ function isPluginTypeValid (value: any) {
function isPluginNameValid (value: string) {
return exists(value) &&
validator.isLength(value, PLUGINS_CONSTRAINTS_FIELDS.NAME) &&
validator.matches(value, /^[a-z\-]+$/)
validator.matches(value, /^[a-z-]+$/)
}
function isNpmPluginNameValid (value: string) {
@ -146,8 +146,8 @@ function isPackageJSONValid (packageJSON: PluginPackageJson, pluginType: PluginT
}
function isLibraryCodeValid (library: any) {
return typeof library.register === 'function'
&& typeof library.unregister === 'function'
return typeof library.register === 'function' &&
typeof library.unregister === 'function'
}
export {

View File

@ -9,7 +9,8 @@ function isUserNotificationTypeValid (value: any) {
function isUserNotificationSettingValid (value: any) {
return exists(value) &&
validator.isInt('' + value) && (
validator.isInt('' + value) &&
(
value === UserNotificationSettingValue.NONE ||
value === UserNotificationSettingValue.WEB ||
value === UserNotificationSettingValue.EMAIL ||

View File

@ -1,8 +1,6 @@
import { Response } from 'express'
import validator from 'validator'
import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants'
import { exists } from './misc'
import { VideoAbuseModel } from '../../models/video/video-abuse'
const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
@ -15,7 +13,7 @@ function isVideoAbuseModerationCommentValid (value: string) {
}
function isVideoAbuseStateValid (value: string) {
return exists(value) && VIDEO_ABUSE_STATES[ value ] !== undefined
return exists(value) && VIDEO_ABUSE_STATES[value] !== undefined
}
// ---------------------------------------------------------------------------

View File

@ -2,7 +2,7 @@ import { CONSTRAINTS_FIELDS, MIMETYPES, VIDEO_LANGUAGES } from '../../initialize
import { exists, isFileValid } from './misc'
function isVideoCaptionLanguageValid (value: any) {
return exists(value) && VIDEO_LANGUAGES[ value ] !== undefined
return exists(value) && VIDEO_LANGUAGES[value] !== undefined
}
const videoCaptionTypes = Object.keys(MIMETYPES.VIDEO_CAPTIONS.MIMETYPE_EXT)

View File

@ -20,7 +20,7 @@ function isVideoImportTargetUrlValid (url: string) {
}
function isVideoImportStateValid (value: any) {
return exists(value) && VIDEO_IMPORT_STATES[ value ] !== undefined
return exists(value) && VIDEO_IMPORT_STATES[value] !== undefined
}
const videoTorrentImportTypes = Object.keys(MIMETYPES.TORRENT.MIMETYPE_EXT).map(m => `(${m})`)

View File

@ -1,8 +1,6 @@
import { exists } from './misc'
import validator from 'validator'
import { CONSTRAINTS_FIELDS, VIDEO_PLAYLIST_PRIVACIES, VIDEO_PLAYLIST_TYPES } from '../../initializers/constants'
import * as express from 'express'
import { VideoPlaylistModel } from '../../models/video/video-playlist'
const PLAYLISTS_CONSTRAINT_FIELDS = CONSTRAINTS_FIELDS.VIDEO_PLAYLISTS
@ -15,7 +13,7 @@ function isVideoPlaylistDescriptionValid (value: any) {
}
function isVideoPlaylistPrivacyValid (value: number) {
return validator.isInt(value + '') && VIDEO_PLAYLIST_PRIVACIES[ value ] !== undefined
return validator.isInt(value + '') && VIDEO_PLAYLIST_PRIVACIES[value] !== undefined
}
function isVideoPlaylistTimestampValid (value: any) {
@ -23,7 +21,7 @@ function isVideoPlaylistTimestampValid (value: any) {
}
function isVideoPlaylistTypeValid (value: any) {
return exists(value) && VIDEO_PLAYLIST_TYPES[ value ] !== undefined
return exists(value) && VIDEO_PLAYLIST_TYPES[value] !== undefined
}
// ---------------------------------------------------------------------------

View File

@ -20,15 +20,15 @@ function isVideoFilterValid (filter: VideoFilter) {
}
function isVideoCategoryValid (value: any) {
return value === null || VIDEO_CATEGORIES[ value ] !== undefined
return value === null || VIDEO_CATEGORIES[value] !== undefined
}
function isVideoStateValid (value: any) {
return exists(value) && VIDEO_STATES[ value ] !== undefined
return exists(value) && VIDEO_STATES[value] !== undefined
}
function isVideoLicenceValid (value: any) {
return value === null || VIDEO_LICENCES[ value ] !== undefined
return value === null || VIDEO_LICENCES[value] !== undefined
}
function isVideoLanguageValid (value: any) {
@ -98,7 +98,7 @@ function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } |
}
function isVideoPrivacyValid (value: number) {
return VIDEO_PRIVACIES[ value ] !== undefined
return VIDEO_PRIVACIES[value] !== undefined
}
function isScheduleVideoUpdatePrivacyValid (value: number) {

View File

@ -12,7 +12,7 @@ function buildNSFWFilter (res?: express.Response, paramNSFW?: string) {
if (paramNSFW === 'false') return false
if (paramNSFW === 'both') return undefined
if (res && res.locals.oauth) {
if (res?.locals.oauth) {
const user = res.locals.oauth.token.User
// User does not want NSFW videos
@ -28,7 +28,7 @@ function buildNSFWFilter (res?: express.Response, paramNSFW?: string) {
return null
}
function cleanUpReqFiles (req: { files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[] }) {
function cleanUpReqFiles (req: { files: { [fieldname: string]: Express.Multer.File[] } | Express.Multer.File[] }) {
const files = req.files
if (!files) return
@ -39,7 +39,7 @@ function cleanUpReqFiles (req: { files: { [ fieldname: string ]: Express.Multer.
}
for (const key of Object.keys(files)) {
const file = files[ key ]
const file = files[key]
if (isArray(file)) file.forEach(f => deleteFileAsync(f.path))
else deleteFileAsync(file.path)
@ -65,18 +65,18 @@ function badRequest (req: express.Request, res: express.Response) {
function createReqFiles (
fieldNames: string[],
mimeTypes: { [ id: string ]: string },
destinations: { [ fieldName: string ]: string }
mimeTypes: { [id: string]: string },
destinations: { [fieldName: string]: string }
) {
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, destinations[ file.fieldname ])
cb(null, destinations[file.fieldname])
},
filename: async (req, file, cb) => {
let extension: string
const fileExtension = extname(file.originalname)
const extensionFromMimetype = mimeTypes[ file.mimetype ]
const extensionFromMimetype = mimeTypes[file.mimetype]
// Take the file extension if we don't understand the mime type
// We have the OGG/OGV exception too because firefox sends a bad mime type when sending an OGG file
@ -99,7 +99,7 @@ function createReqFiles (
}
})
let fields: { name: string, maxCount: number }[] = []
const fields: { name: string, maxCount: number }[] = []
for (const fieldName of fieldNames) {
fields.push({
name: fieldName,

View File

@ -1,6 +1,6 @@
import * as ffmpeg from 'fluent-ffmpeg'
import { dirname, join } from 'path'
import { getTargetBitrate, getMaxBitrate, VideoResolution } from '../../shared/models/videos'
import { getMaxBitrate, getTargetBitrate, VideoResolution } from '../../shared/models/videos'
import { FFMPEG_NICE, VIDEO_TRANSCODING_FPS } from '../initializers/constants'
import { processImage } from './image-utils'
import { logger } from './logger'
@ -8,6 +8,71 @@ import { checkFFmpegEncoders } from '../initializers/checker-before-init'
import { readFile, remove, writeFile } from 'fs-extra'
import { CONFIG } from '../initializers/config'
/**
* A toolbox to play with audio
*/
namespace audio {
export const get = (videoPath: string) => {
// without position, ffprobe considers the last input only
// we make it consider the first input only
// if you pass a file path to pos, then ffprobe acts on that file directly
return new Promise<{ absolutePath: string, audioStream?: any }>((res, rej) => {
function parseFfprobe (err: any, data: ffmpeg.FfprobeData) {
if (err) return rej(err)
if ('streams' in data) {
const audioStream = data.streams.find(stream => stream['codec_type'] === 'audio')
if (audioStream) {
return res({
absolutePath: data.format.filename,
audioStream
})
}
}
return res({ absolutePath: data.format.filename })
}
return ffmpeg.ffprobe(videoPath, parseFfprobe)
})
}
export namespace bitrate {
const baseKbitrate = 384
const toBits = (kbits: number) => kbits * 8000
export const aac = (bitrate: number): number => {
switch (true) {
case bitrate > toBits(baseKbitrate):
return baseKbitrate
default:
return -1 // we interpret it as a signal to copy the audio stream as is
}
}
export const mp3 = (bitrate: number): number => {
/*
a 192kbit/sec mp3 doesn't hold as much information as a 192kbit/sec aac.
That's why, when using aac, we can go to lower kbit/sec. The equivalences
made here are not made to be accurate, especially with good mp3 encoders.
*/
switch (true) {
case bitrate <= toBits(192):
return 128
case bitrate <= toBits(384):
return 256
default:
return baseKbitrate
}
}
}
}
function computeResolutionsToTranscode (videoFileHeight: number) {
const resolutionsEnabled: number[] = []
const configResolutions = CONFIG.TRANSCODING.RESOLUTIONS
@ -24,7 +89,7 @@ function computeResolutionsToTranscode (videoFileHeight: number) {
]
for (const resolution of resolutions) {
if (configResolutions[ resolution + 'p' ] === true && videoFileHeight > resolution) {
if (configResolutions[resolution + 'p'] === true && videoFileHeight > resolution) {
resolutionsEnabled.push(resolution)
}
}
@ -48,9 +113,9 @@ async function getVideoStreamCodec (path: string) {
const videoCodec = videoStream.codec_tag_string
const baseProfileMatrix = {
'High': '6400',
'Main': '4D40',
'Baseline': '42E0'
High: '6400',
Main: '4D40',
Baseline: '42E0'
}
let baseProfile = baseProfileMatrix[videoStream.profile]
@ -91,7 +156,7 @@ async function getVideoFileFPS (path: string) {
if (videoStream === null) return 0
for (const key of [ 'avg_frame_rate', 'r_frame_rate' ]) {
const valuesText: string = videoStream[ key ]
const valuesText: string = videoStream[key]
if (!valuesText) continue
const [ frames, seconds ] = valuesText.split('/')
@ -191,7 +256,8 @@ interface OnlyAudioTranscodeOptions extends BaseTranscodeOptions {
type: 'only-audio'
}
type TranscodeOptions = HLSTranscodeOptions
type TranscodeOptions =
HLSTranscodeOptions
| VideoTranscodeOptions
| MergeAudioTranscodeOptions
| OnlyAudioTranscodeOptions
@ -204,13 +270,13 @@ function transcode (options: TranscodeOptions) {
.output(options.outputPath)
if (options.type === 'quick-transcode') {
command = await buildQuickTranscodeCommand(command)
command = buildQuickTranscodeCommand(command)
} else if (options.type === 'hls') {
command = await buildHLSCommand(command, options)
} else if (options.type === 'merge-audio') {
command = await buildAudioMergeCommand(command, options)
} else if (options.type === 'only-audio') {
command = await buildOnlyAudioCommand(command, options)
command = buildOnlyAudioCommand(command, options)
} else {
command = await buildx264Command(command, options)
}
@ -247,17 +313,17 @@ async function canDoQuickTranscode (path: string): Promise<boolean> {
// check video params
if (videoStream == null) return false
if (videoStream[ 'codec_name' ] !== 'h264') return false
if (videoStream[ 'pix_fmt' ] !== 'yuv420p') return false
if (videoStream['codec_name'] !== 'h264') return false
if (videoStream['pix_fmt'] !== 'yuv420p') return false
if (fps < VIDEO_TRANSCODING_FPS.MIN || fps > VIDEO_TRANSCODING_FPS.MAX) return false
if (bitRate > getMaxBitrate(resolution.videoFileResolution, fps, VIDEO_TRANSCODING_FPS)) return false
// check audio params (if audio stream exists)
if (parsedAudio.audioStream) {
if (parsedAudio.audioStream[ 'codec_name' ] !== 'aac') return false
if (parsedAudio.audioStream['codec_name'] !== 'aac') return false
const maxAudioBitrate = audio.bitrate[ 'aac' ](parsedAudio.audioStream[ 'bit_rate' ])
if (maxAudioBitrate !== -1 && parsedAudio.audioStream[ 'bit_rate' ] > maxAudioBitrate) return false
const maxAudioBitrate = audio.bitrate['aac'](parsedAudio.audioStream['bit_rate'])
if (maxAudioBitrate !== -1 && parsedAudio.audioStream['bit_rate'] > maxAudioBitrate) return false
}
return true
@ -333,14 +399,14 @@ async function buildAudioMergeCommand (command: ffmpeg.FfmpegCommand, options: M
return command
}
async function buildOnlyAudioCommand (command: ffmpeg.FfmpegCommand, options: OnlyAudioTranscodeOptions) {
command = await presetOnlyAudio(command)
function buildOnlyAudioCommand (command: ffmpeg.FfmpegCommand, options: OnlyAudioTranscodeOptions) {
command = presetOnlyAudio(command)
return command
}
async function buildQuickTranscodeCommand (command: ffmpeg.FfmpegCommand) {
command = await presetCopy(command)
function buildQuickTranscodeCommand (command: ffmpeg.FfmpegCommand) {
command = presetCopy(command)
command = command.outputOption('-map_metadata -1') // strip all metadata
.outputOption('-movflags faststart')
@ -351,7 +417,7 @@ async function buildQuickTranscodeCommand (command: ffmpeg.FfmpegCommand) {
async function buildHLSCommand (command: ffmpeg.FfmpegCommand, options: HLSTranscodeOptions) {
const videoPath = getHLSVideoPath(options)
if (options.copyCodecs) command = await presetCopy(command)
if (options.copyCodecs) command = presetCopy(command)
else command = await buildx264Command(command, options)
command = command.outputOption('-hls_time 4')
@ -418,71 +484,6 @@ async function presetH264VeryFast (command: ffmpeg.FfmpegCommand, input: string,
return localCommand
}
/**
* A toolbox to play with audio
*/
namespace audio {
export const get = (videoPath: string) => {
// without position, ffprobe considers the last input only
// we make it consider the first input only
// if you pass a file path to pos, then ffprobe acts on that file directly
return new Promise<{ absolutePath: string, audioStream?: any }>((res, rej) => {
function parseFfprobe (err: any, data: ffmpeg.FfprobeData) {
if (err) return rej(err)
if ('streams' in data) {
const audioStream = data.streams.find(stream => stream[ 'codec_type' ] === 'audio')
if (audioStream) {
return res({
absolutePath: data.format.filename,
audioStream
})
}
}
return res({ absolutePath: data.format.filename })
}
return ffmpeg.ffprobe(videoPath, parseFfprobe)
})
}
export namespace bitrate {
const baseKbitrate = 384
const toBits = (kbits: number) => kbits * 8000
export const aac = (bitrate: number): number => {
switch (true) {
case bitrate > toBits(baseKbitrate):
return baseKbitrate
default:
return -1 // we interpret it as a signal to copy the audio stream as is
}
}
export const mp3 = (bitrate: number): number => {
/*
a 192kbit/sec mp3 doesn't hold as much information as a 192kbit/sec aac.
That's why, when using aac, we can go to lower kbit/sec. The equivalences
made here are not made to be accurate, especially with good mp3 encoders.
*/
switch (true) {
case bitrate <= toBits(192):
return 128
case bitrate <= toBits(384):
return 256
default:
return baseKbitrate
}
}
}
}
/**
* Standard profile, with variable bitrate audio and faststart.
*
@ -513,10 +514,10 @@ async function presetH264 (command: ffmpeg.FfmpegCommand, input: string, resolut
// of course this is far from perfect, but it might save some space in the end
localCommand = localCommand.audioCodec('aac')
const audioCodecName = parsedAudio.audioStream[ 'codec_name' ]
const audioCodecName = parsedAudio.audioStream['codec_name']
if (audio.bitrate[ audioCodecName ]) {
const bitrate = audio.bitrate[ audioCodecName ](parsedAudio.audioStream[ 'bit_rate' ])
if (audio.bitrate[audioCodecName]) {
const bitrate = audio.bitrate[audioCodecName](parsedAudio.audioStream['bit_rate'])
if (bitrate !== undefined && bitrate !== -1) localCommand = localCommand.audioBitrate(bitrate)
}
}
@ -537,14 +538,14 @@ async function presetH264 (command: ffmpeg.FfmpegCommand, input: string, resolut
return localCommand
}
async function presetCopy (command: ffmpeg.FfmpegCommand): Promise<ffmpeg.FfmpegCommand> {
function presetCopy (command: ffmpeg.FfmpegCommand): ffmpeg.FfmpegCommand {
return command
.format('mp4')
.videoCodec('copy')
.audioCodec('copy')
}
async function presetOnlyAudio (command: ffmpeg.FfmpegCommand): Promise<ffmpeg.FfmpegCommand> {
function presetOnlyAudio (command: ffmpeg.FfmpegCommand): ffmpeg.FfmpegCommand {
return command
.format('mp4')
.audioCodec('copy')

View File

@ -27,7 +27,7 @@ function getLoggerReplacer () {
if (value instanceof Error) {
const error = {}
Object.getOwnPropertyNames(value).forEach(key => error[ key ] = value[ key ])
Object.getOwnPropertyNames(value).forEach(key => { error[key] = value[key] })
return error
}
@ -98,19 +98,20 @@ function bunyanLogFactory (level: string) {
let args: any[] = []
args.concat(arguments)
if (arguments[ 0 ] instanceof Error) {
meta = arguments[ 0 ].toString()
if (arguments[0] instanceof Error) {
meta = arguments[0].toString()
args = Array.prototype.slice.call(arguments, 1)
args.push(meta)
} else if (typeof (args[ 0 ]) !== 'string') {
meta = arguments[ 0 ]
} else if (typeof (args[0]) !== 'string') {
meta = arguments[0]
args = Array.prototype.slice.call(arguments, 1)
args.push(meta)
}
logger[ level ].apply(logger, args)
logger[level].apply(logger, args)
}
}
const bunyanLogger = {
trace: bunyanLogFactory('debug'),
debug: bunyanLogFactory('debug'),

View File

@ -1,8 +1,8 @@
// Thanks to https://regex101.com
function regexpCapture (str: string, regex: RegExp, maxIterations = 100) {
const result: RegExpExecArray[] = []
let m: RegExpExecArray
let i = 0
let result: RegExpExecArray[] = []
// tslint:disable:no-conditional-assignment
while ((m = regex.exec(str)) !== null && i < maxIterations) {

View File

@ -1,5 +1,5 @@
import { resolve } from 'path'
const tsConfigPaths = require('tsconfig-paths')
import tsConfigPaths = require('tsconfig-paths')
const tsConfig = require('../../tsconfig.json')

View File

@ -21,7 +21,7 @@ async function isSignupAllowed (): Promise<{ allowed: boolean, errorMessage?: st
function isSignupAllowedForCurrentIP (ip: string) {
const addr = ipaddr.parse(ip)
let excludeList = [ 'blacklist' ]
const excludeList = [ 'blacklist' ]
let matched = ''
// if there is a valid, non-empty whitelist, we exclude all unknown adresses too

View File

@ -1,6 +1,6 @@
import { ResultList } from '../../shared'
import { ApplicationModel } from '../models/application/application'
import { execPromise, execPromise2, pseudoRandomBytesPromise, sha256 } from './core-utils'
import { execPromise, execPromise2, randomBytesPromise, sha256 } from './core-utils'
import { logger } from './logger'
import { join } from 'path'
import { Instance as ParseTorrent } from 'parse-torrent'
@ -14,7 +14,7 @@ function deleteFileAsync (path: string) {
}
async function generateRandomString (size: number) {
const raw = await pseudoRandomBytesPromise(size)
const raw = await randomBytesPromise(size)
return raw.toString('hex')
}

View File

@ -39,7 +39,7 @@ async function downloadWebTorrentVideo (target: { magnetUri: string, torrentName
if (torrent.files.length !== 1) {
if (timer) clearTimeout(timer)
for (let file of torrent.files) {
for (const file of torrent.files) {
deleteDownloadedFile({ directoryPath, filepath: file.path })
}
@ -47,15 +47,16 @@ async function downloadWebTorrentVideo (target: { magnetUri: string, torrentName
.then(() => rej(new Error('Cannot import torrent ' + torrentId + ': there are multiple files in it')))
}
file = torrent.files[ 0 ]
file = torrent.files[0]
// FIXME: avoid creating another stream when https://github.com/webtorrent/webtorrent/issues/1517 is fixed
const writeStream = createWriteStream(path)
writeStream.on('finish', () => {
if (timer) clearTimeout(timer)
return safeWebtorrentDestroy(webtorrent, torrentId, { directoryPath, filepath: file.path }, target.torrentName)
safeWebtorrentDestroy(webtorrent, torrentId, { directoryPath, filepath: file.path }, target.torrentName)
.then(() => res(path))
.catch(err => logger.error('Cannot destroy webtorrent.', { err }))
})
file.createReadStream().pipe(writeStream)
@ -63,9 +64,16 @@ async function downloadWebTorrentVideo (target: { magnetUri: string, torrentName
torrent.on('error', err => rej(err))
timer = setTimeout(async () => {
return safeWebtorrentDestroy(webtorrent, torrentId, file ? { directoryPath, filepath: file.path } : undefined, target.torrentName)
.then(() => rej(new Error('Webtorrent download timeout.')))
timer = setTimeout(() => {
const err = new Error('Webtorrent download timeout.')
safeWebtorrentDestroy(webtorrent, torrentId, file ? { directoryPath, filepath: file.path } : undefined, target.torrentName)
.then(() => rej(err))
.catch(destroyErr => {
logger.error('Cannot destroy webtorrent.', { err: destroyErr })
rej(err)
})
}, timeout)
})
}

View File

@ -24,20 +24,23 @@ const processOptions = {
}
function getYoutubeDLInfo (url: string, opts?: string[]): Promise<YoutubeDLInfo> {
return new Promise<YoutubeDLInfo>(async (res, rej) => {
return new Promise<YoutubeDLInfo>((res, rej) => {
let args = opts || [ '-j', '--flat-playlist' ]
args = wrapWithProxyOptions(args)
const youtubeDL = await safeGetYoutubeDL()
youtubeDL.getInfo(url, args, processOptions, (err, info) => {
if (err) return rej(err)
if (info.is_live === true) return rej(new Error('Cannot download a live streaming.'))
safeGetYoutubeDL()
.then(youtubeDL => {
youtubeDL.getInfo(url, args, processOptions, (err, info) => {
if (err) return rej(err)
if (info.is_live === true) return rej(new Error('Cannot download a live streaming.'))
const obj = buildVideoInfo(normalizeObject(info))
if (obj.name && obj.name.length < CONSTRAINTS_FIELDS.VIDEOS.NAME.min) obj.name += ' video'
const obj = buildVideoInfo(normalizeObject(info))
if (obj.name && obj.name.length < CONSTRAINTS_FIELDS.VIDEOS.NAME.min) obj.name += ' video'
return res(obj)
})
return res(obj)
})
})
.catch(err => rej(err))
})
}
@ -54,26 +57,34 @@ function downloadYoutubeDLVideo (url: string, timeout: number) {
options = options.concat([ '--ffmpeg-location', process.env.FFMPEG_PATH ])
}
return new Promise<string>(async (res, rej) => {
const youtubeDL = await safeGetYoutubeDL()
youtubeDL.exec(url, options, processOptions, err => {
clearTimeout(timer)
return new Promise<string>((res, rej) => {
safeGetYoutubeDL()
.then(youtubeDL => {
youtubeDL.exec(url, options, processOptions, err => {
clearTimeout(timer)
if (err) {
remove(path)
.catch(err => logger.error('Cannot delete path on YoutubeDL error.', { err }))
if (err) {
remove(path)
.catch(err => logger.error('Cannot delete path on YoutubeDL error.', { err }))
return rej(err)
}
return rej(err)
}
return res(path)
})
return res(path)
})
timer = setTimeout(async () => {
await remove(path)
timer = setTimeout(() => {
const err = new Error('YoutubeDL download timeout.')
return rej(new Error('YoutubeDL download timeout.'))
}, timeout)
remove(path)
.finally(() => rej(err))
.catch(err => {
logger.error('Cannot remove %s in youtubeDL timeout.', path, { err })
return rej(err)
})
}, timeout)
})
.catch(err => rej(err))
})
}
@ -103,7 +114,7 @@ async function updateYoutubeDLBinary () {
const url = result.headers.location
const downloadFile = request.get(url)
const newVersion = /yt-dl\.org\/downloads\/(\d{4}\.\d\d\.\d\d(\.\d)?)\/youtube-dl/.exec(url)[ 1 ]
const newVersion = /yt-dl\.org\/downloads\/(\d{4}\.\d\d\.\d\d(\.\d)?)\/youtube-dl/.exec(url)[1]
downloadFile.on('response', result => {
if (result.statusCode !== 200) {

View File

@ -3,7 +3,7 @@ import { isProdInstance, isTestInstance } from '../helpers/core-utils'
import { UserModel } from '../models/account/user'
import { ApplicationModel } from '../models/application/application'
import { OAuthClientModel } from '../models/oauth/oauth-client'
import { parse } from 'url'
import { URL } from 'url'
import { CONFIG } from './config'
import { logger } from '../helpers/logger'
import { getServerActor } from '../helpers/utils'
@ -16,7 +16,7 @@ import { WEBSERVER } from './constants'
async function checkActivityPubUrls () {
const actor = await getServerActor()
const parsed = parse(actor.url)
const parsed = new URL(actor.url)
if (WEBSERVER.HOST !== parsed.host) {
const NODE_ENV = config.util.getEnv('NODE_ENV')
const NODE_CONFIG_DIR = config.util.getEnv('NODE_CONFIG_DIR')

View File

@ -35,8 +35,8 @@ function checkMissedConfig () {
]
const requiredAlternatives = [
[ // set
['redis.hostname', 'redis.port'], // alternative
['redis.socket']
[ 'redis.hostname', 'redis.port' ], // alternative
[ 'redis.socket' ]
]
]
const miss: string[] = []

View File

@ -301,7 +301,7 @@ function getLocalConfigFilePath () {
if (process.env.NODE_ENV) filename += `-${process.env.NODE_ENV}`
if (process.env.NODE_APP_INSTANCE) filename += `-${process.env.NODE_APP_INSTANCE}`
return join(dirname(configSources[ 0 ].name), filename + '.json')
return join(dirname(configSources[0].name), filename + '.json')
}
function buildVideosRedundancy (objs: any[]): VideosRedundancyStrategy[] {
@ -330,7 +330,7 @@ export function reloadConfig () {
function purge () {
for (const fileName in require.cache) {
if (-1 === fileName.indexOf(directory())) {
if (fileName.indexOf(directory()) === -1) {
continue
}

View File

@ -4,7 +4,7 @@ import { ActivityPubActorType } from '../../shared/models/activitypub'
import { FollowState } from '../../shared/models/actors'
import { VideoAbuseState, VideoImportState, VideoPrivacy, VideoTranscodingFPS } from '../../shared/models/videos'
// Do not use barrels, remain constants as independent as possible
import { isTestInstance, sanitizeHost, sanitizeUrl, root, parseDurationToMs } from '../helpers/core-utils'
import { isTestInstance, sanitizeHost, sanitizeUrl, root } from '../helpers/core-utils'
import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type'
import { invert } from 'lodash'
import { CronRepeatOptions, EveryRepeatOptions } from 'bull'
@ -310,8 +310,8 @@ let CONTACT_FORM_LIFETIME = 60000 * 60 // 1 hour
const VIDEO_TRANSCODING_FPS: VideoTranscodingFPS = {
MIN: 10,
STANDARD: [24, 25, 30],
HD_STANDARD: [50, 60],
STANDARD: [ 24, 25, 30 ],
HD_STANDARD: [ 50, 60 ],
AVERAGE: 30,
MAX: 60,
KEEP_ORIGIN_FPS_RESOLUTION_MIN: 720 // We keep the original FPS on high resolutions (720 minimum)
@ -361,42 +361,42 @@ const VIDEO_LICENCES = {
7: 'Public Domain Dedication'
}
let VIDEO_LANGUAGES: { [id: string]: string } = {}
const VIDEO_LANGUAGES: { [id: string]: string } = {}
const VIDEO_PRIVACIES = {
[ VideoPrivacy.PUBLIC ]: 'Public',
[ VideoPrivacy.UNLISTED ]: 'Unlisted',
[ VideoPrivacy.PRIVATE ]: 'Private',
[ VideoPrivacy.INTERNAL ]: 'Internal'
[VideoPrivacy.PUBLIC]: 'Public',
[VideoPrivacy.UNLISTED]: 'Unlisted',
[VideoPrivacy.PRIVATE]: 'Private',
[VideoPrivacy.INTERNAL]: 'Internal'
}
const VIDEO_STATES = {
[ VideoState.PUBLISHED ]: 'Published',
[ VideoState.TO_TRANSCODE ]: 'To transcode',
[ VideoState.TO_IMPORT ]: 'To import'
[VideoState.PUBLISHED]: 'Published',
[VideoState.TO_TRANSCODE]: 'To transcode',
[VideoState.TO_IMPORT]: 'To import'
}
const VIDEO_IMPORT_STATES = {
[ VideoImportState.FAILED ]: 'Failed',
[ VideoImportState.PENDING ]: 'Pending',
[ VideoImportState.SUCCESS ]: 'Success'
[VideoImportState.FAILED]: 'Failed',
[VideoImportState.PENDING]: 'Pending',
[VideoImportState.SUCCESS]: 'Success'
}
const VIDEO_ABUSE_STATES = {
[ VideoAbuseState.PENDING ]: 'Pending',
[ VideoAbuseState.REJECTED ]: 'Rejected',
[ VideoAbuseState.ACCEPTED ]: 'Accepted'
[VideoAbuseState.PENDING]: 'Pending',
[VideoAbuseState.REJECTED]: 'Rejected',
[VideoAbuseState.ACCEPTED]: 'Accepted'
}
const VIDEO_PLAYLIST_PRIVACIES = {
[ VideoPlaylistPrivacy.PUBLIC ]: 'Public',
[ VideoPlaylistPrivacy.UNLISTED ]: 'Unlisted',
[ VideoPlaylistPrivacy.PRIVATE ]: 'Private'
[VideoPlaylistPrivacy.PUBLIC]: 'Public',
[VideoPlaylistPrivacy.UNLISTED]: 'Unlisted',
[VideoPlaylistPrivacy.PRIVATE]: 'Private'
}
const VIDEO_PLAYLIST_TYPES = {
[ VideoPlaylistType.REGULAR ]: 'Regular',
[ VideoPlaylistType.WATCH_LATER ]: 'Watch later'
[VideoPlaylistType.REGULAR]: 'Regular',
[VideoPlaylistType.WATCH_LATER]: 'Watch later'
}
const MIMETYPES = {
@ -533,7 +533,7 @@ const LAZY_STATIC_PATHS = {
}
// Cache control
let STATIC_MAX_AGE = {
const STATIC_MAX_AGE = {
SERVER: '2h',
CLIENT: '30d'
}
@ -671,14 +671,14 @@ if (isTestInstance() === true) {
SCHEDULER_INTERVALS_MS.removeOldViews = 5000
SCHEDULER_INTERVALS_MS.updateVideos = 5000
SCHEDULER_INTERVALS_MS.autoFollowIndexInstances = 5000
REPEAT_JOBS[ 'videos-views' ] = { every: 5000 }
REPEAT_JOBS['videos-views'] = { every: 5000 }
REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1
VIDEO_VIEW_LIFETIME = 1000 // 1 second
CONTACT_FORM_LIFETIME = 1000 // 1 second
JOB_ATTEMPTS[ 'email' ] = 1
JOB_ATTEMPTS['email'] = 1
FILES_CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000
MEMOIZE_TTL.OVERVIEWS_SAMPLE = 1
@ -838,42 +838,42 @@ function loadLanguages () {
function buildLanguages () {
const iso639 = require('iso-639-3')
const languages: { [ id: string ]: string } = {}
const languages: { [id: string]: string } = {}
const additionalLanguages = {
'sgn': true, // Sign languages (macro language)
'ase': true, // American sign language
'sdl': true, // Arabian sign language
'bfi': true, // British sign language
'bzs': true, // Brazilian sign language
'csl': true, // Chinese sign language
'cse': true, // Czech sign language
'dsl': true, // Danish sign language
'fsl': true, // French sign language
'gsg': true, // German sign language
'pks': true, // Pakistan sign language
'jsl': true, // Japanese sign language
'sfs': true, // South African sign language
'swl': true, // Swedish sign language
'rsl': true, // Russian sign language: true
sgn: true, // Sign languages (macro language)
ase: true, // American sign language
sdl: true, // Arabian sign language
bfi: true, // British sign language
bzs: true, // Brazilian sign language
csl: true, // Chinese sign language
cse: true, // Czech sign language
dsl: true, // Danish sign language
fsl: true, // French sign language
gsg: true, // German sign language
pks: true, // Pakistan sign language
jsl: true, // Japanese sign language
sfs: true, // South African sign language
swl: true, // Swedish sign language
rsl: true, // Russian sign language: true
'epo': true, // Esperanto
'tlh': true, // Klingon
'jbo': true, // Lojban
'avk': true // Kotava
epo: true, // Esperanto
tlh: true, // Klingon
jbo: true, // Lojban
avk: true // Kotava
}
// Only add ISO639-1 languages and some sign languages (ISO639-3)
iso639
.filter(l => {
return (l.iso6391 !== null && l.type === 'living') ||
additionalLanguages[ l.iso6393 ] === true
additionalLanguages[l.iso6393] === true
})
.forEach(l => languages[ l.iso6391 || l.iso6393 ] = l.name)
.forEach(l => { languages[l.iso6391 || l.iso6393] = l.name })
// Override Occitan label
languages[ 'oc' ] = 'Occitan'
languages[ 'el' ] = 'Greek'
languages['oc'] = 'Occitan'
languages['el'] = 'Greek'
return languages
}

View File

@ -119,8 +119,6 @@ async function initDatabaseModels (silent: boolean) {
await createFunctions()
if (!silent) logger.info('Database %s is ready.', dbname)
return
}
// ---------------------------------------------------------------------------

View File

@ -3,8 +3,8 @@ import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const q = utils.queryInterface

View File

@ -3,8 +3,8 @@ import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const q = utils.queryInterface

View File

@ -2,8 +2,8 @@ import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const q = utils.queryInterface

View File

@ -2,8 +2,8 @@ import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const q = utils.queryInterface

View File

@ -2,8 +2,8 @@ import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const q = utils.queryInterface

View File

@ -3,8 +3,8 @@ import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const q = utils.queryInterface

View File

@ -3,8 +3,8 @@ import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const q = utils.queryInterface

View File

@ -3,8 +3,8 @@ import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const q = utils.queryInterface

View File

@ -2,8 +2,8 @@ import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const q = utils.queryInterface

View File

@ -2,8 +2,8 @@ import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const q = utils.queryInterface

View File

@ -3,8 +3,8 @@ import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const q = utils.queryInterface

View File

@ -2,9 +2,9 @@ import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
const q = utils.queryInterface

View File

@ -5,9 +5,9 @@ import { VideoModel } from '../../models/video/video'
import { getVideoFilePath } from '@server/lib/video-paths'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
return utils.db.Video.listOwnedAndPopulateAuthorAndTags()

View File

@ -3,9 +3,9 @@ import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
const q = utils.queryInterface

View File

@ -5,9 +5,9 @@ import { getVideoFileResolution } from '../../helpers/ffmpeg-utils'
import { readdir, rename } from 'fs-extra'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
const torrentDir = CONFIG.STORAGE.TORRENTS_DIR

View File

@ -2,9 +2,9 @@ import * as Sequelize from 'sequelize'
import * as uuidv4 from 'uuid/v4'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
const q = utils.queryInterface

View File

@ -1,9 +1,9 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
const q = utils.queryInterface

View File

@ -1,9 +1,9 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
const q = utils.queryInterface

View File

@ -1,9 +1,9 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
const q = utils.queryInterface

View File

@ -7,9 +7,9 @@ import { ApplicationModel } from '../../models/application/application'
import { SERVER_ACTOR_NAME } from '../constants'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
const q = utils.queryInterface

View File

@ -1,9 +1,9 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
await utils.queryInterface.removeColumn('Servers', 'email')

View File

@ -1,9 +1,9 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
await utils.queryInterface.removeColumn('Servers', 'publicKey')

View File

@ -1,9 +1,9 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
await utils.db.Avatar.sync()

View File

@ -1,9 +1,9 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
await utils.queryInterface.renameTable('Applications', 'application')

View File

@ -2,8 +2,8 @@ import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const q = utils.queryInterface

View File

@ -3,8 +3,8 @@ import { DataType } from 'sequelize-typescript'
import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
// Create actor table
@ -64,10 +64,10 @@ async function up (utils: {
type, uuid, "preferredUsername", url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
"sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
)
SELECT
SELECT
'Application', uuid, name, url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
"sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
FROM account
"sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
FROM account
WHERE "applicationId" IS NOT NULL
`
await utils.sequelize.query(query1)
@ -79,10 +79,10 @@ async function up (utils: {
type, uuid, "preferredUsername", url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
"sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
)
SELECT
SELECT
'Person', uuid, name, url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
"sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
FROM account
"sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
FROM account
WHERE "applicationId" IS NULL
`
await utils.sequelize.query(query2)
@ -108,17 +108,17 @@ async function up (utils: {
}
{
const query = `
INSERT INTO actor
const query = `
INSERT INTO actor
(
type, uuid, "preferredUsername", url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
type, uuid, "preferredUsername", url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
"sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
)
SELECT
'Group', "videoChannel".uuid, "videoChannel".uuid, "videoChannel".url, null, null, 0, 0, "videoChannel".url || '/inbox',
SELECT
'Group', "videoChannel".uuid, "videoChannel".uuid, "videoChannel".url, null, null, 0, 0, "videoChannel".url || '/inbox',
"videoChannel".url || '/outbox', "videoChannel".url || '/inbox', "videoChannel".url || '/followers', "videoChannel".url || '/following',
null, account."serverId", "videoChannel"."createdAt", "videoChannel"."updatedAt"
FROM "videoChannel"
null, account."serverId", "videoChannel"."createdAt", "videoChannel"."updatedAt"
FROM "videoChannel"
INNER JOIN "account" on "videoChannel"."accountId" = "account".id
`
await utils.sequelize.query(query)
@ -157,13 +157,13 @@ async function up (utils: {
}
{
const query1 = `UPDATE "actorFollow"
SET "actorId" =
const query1 = `UPDATE "actorFollow"
SET "actorId" =
(SELECT "account"."actorId" FROM account WHERE "account"."id" = "actorFollow"."actorId")`
await utils.sequelize.query(query1)
const query2 = `UPDATE "actorFollow"
SET "targetActorId" =
const query2 = `UPDATE "actorFollow"
SET "targetActorId" =
(SELECT "account"."actorId" FROM account WHERE "account"."id" = "actorFollow"."targetActorId")`
await utils.sequelize.query(query2)
@ -189,8 +189,8 @@ async function up (utils: {
await utils.queryInterface.removeConstraint('videoShare', 'videoShare_accountId_fkey')
}
const query = `UPDATE "videoShare"
SET "actorId" =
const query = `UPDATE "videoShare"
SET "actorId" =
(SELECT "actorId" FROM account WHERE id = "videoShare"."actorId")`
await utils.sequelize.query(query)

View File

@ -2,8 +2,8 @@ import * as Sequelize from 'sequelize'
import { WEBSERVER } from '../constants'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const toReplace = WEBSERVER.HOSTNAME + ':443'

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
await utils.queryInterface.dropTable('Authors')

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
await utils.queryInterface.removeConstraint('actor', 'actor_avatarId_fkey')

View File

@ -2,8 +2,8 @@ import * as Sequelize from 'sequelize'
import { Migration } from '../../models/migrations'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const data = {

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
{

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
{

View File

@ -2,8 +2,8 @@ import * as Sequelize from 'sequelize'
import { ACTOR_FOLLOW_SCORE } from '../constants'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
await utils.queryInterface.removeColumn('server', 'score')

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
const query = 'UPDATE "actor" SET ' +

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
await utils.queryInterface.dropTable('job')

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
{

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
{

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
{

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {

View File

@ -2,8 +2,8 @@ import * as Sequelize from 'sequelize'
import { CONSTRAINTS_FIELDS } from '../constants'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {

View File

@ -1,8 +1,8 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
}): Promise<void> {
{

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize'
import { VideoAbuseState } from '../../../shared/models/videos'
async function up (utils: {
transaction: Sequelize.Transaction

View File

@ -1,9 +1,9 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
{

View File

@ -1,9 +1,9 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
{

View File

@ -1,9 +1,9 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
{

View File

@ -1,9 +1,9 @@
import * as Sequelize from 'sequelize'
async function up (utils: {
transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize,
transaction: Sequelize.Transaction
queryInterface: Sequelize.QueryInterface
sequelize: Sequelize.Sequelize
db: any
}): Promise<void> {
{

Some files were not shown because too many files have changed in this diff Show More