Update server dependencies

This commit is contained in:
Chocobozzz 2021-02-03 09:33:05 +01:00
parent 29f148a613
commit ba5a8d89bb
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
42 changed files with 1322 additions and 1553 deletions

View File

@ -97,13 +97,13 @@
"bull": "^3.4.2",
"bytes": "^3.0.0",
"chokidar": "^3.4.2",
"commander": "^6.0.0",
"commander": "^7.0.0",
"config": "^3.0.0",
"cookie-parser": "^1.4.3",
"cors": "^2.8.1",
"create-torrent": "^4.0.0",
"deep-object-diff": "^1.1.0",
"email-templates": "^7.0.4",
"email-templates": "^8.0.3",
"express": "^4.12.4",
"express-oauth-server": "^2.0.0",
"express-rate-limit": "^5.0.0",
@ -118,12 +118,12 @@
"is-cidr": "^4.0.0",
"iso-639-3": "^2.0.0",
"jimp": "^0.16.0",
"js-yaml": "^3.5.4",
"jsonld": "~3.2.0",
"js-yaml": "^4.0.0",
"jsonld": "~3.3.0",
"lodash": "^4.17.10",
"lru-cache": "^6.0.0",
"magnet-uri": "^6.1.0",
"markdown-it": "12.0.2",
"markdown-it": "12.0.4",
"markdown-it-emoji": "^2.0.0",
"memoizee": "^0.4.14",
"morgan": "^1.5.3",
@ -143,7 +143,7 @@
"request": "^2.81.0",
"sanitize-html": "2.x",
"scripty": "^2.0.0",
"sequelize": "6.3.5",
"sequelize": "6.5.0",
"sequelize-typescript": "^2.0.0-beta.1",
"sitemap": "^6.1.0",
"socket.io": "^3.0.2",
@ -155,7 +155,7 @@
"uuid": "^8.1.0",
"validator": "^13.0.0",
"webfinger.js": "^2.6.6",
"webtorrent": "^0.111.0",
"webtorrent": "^0.112.3",
"winston": "3.3.3",
"ws": "^7.0.0",
"youtube-dl": "^3.0.2"
@ -168,13 +168,13 @@
"@types/bcrypt": "^3.0.0",
"@types/bluebird": "3.5.33",
"@types/body-parser": "^1.16.3",
"@types/bull": "3.14.4",
"@types/bull": "3.15.0",
"@types/bytes": "^3.0.0",
"@types/chai": "^4.0.4",
"@types/chai-json-schema": "^1.4.3",
"@types/chai-xml": "^0.3.1",
"@types/config": "^0.0.36",
"@types/express": "^4.0.35",
"@types/config": "^0.0.38",
"@types/express": "4.17.9",
"@types/express-rate-limit": "^5.0.0",
"@types/fluent-ffmpeg": "^2.1.16",
"@types/fs-extra": "^9.0.1",
@ -188,7 +188,7 @@
"@types/mocha": "^8.0.3",
"@types/morgan": "^1.7.32",
"@types/multer": "^1.3.3",
"@types/node": "^14.0.13",
"@types/node": "^12",
"@types/nodemailer": "^6.2.0",
"@types/oauth2-server": "^3.0.8",
"@types/pem": "^1.9.3",
@ -204,11 +204,11 @@
"chai-xml": "^0.4.0",
"concurrently": "^5.0.0",
"eslint": "^7.2.0",
"eslint-config-standard-with-typescript": "^19.0.1",
"eslint-config-standard-with-typescript": "^20.0.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"eslint-plugin-standard": "^5.0.0",
"libxmljs": "0.19.7",
"maildev": "^1.0.0-rc3",
"marked": "^1.1.0",
@ -219,7 +219,7 @@
"source-map-support": "^0.5.0",
"supertest": "^6.0.1",
"swagger-cli": "^4.0.2",
"ts-node": "9.0.0",
"ts-node": "9.1.1",
"typescript": "^4.0.5"
},
"scripty": {

View File

@ -13,7 +13,9 @@ program
.description('Import a video file to replace an already uploaded file or to add a new resolution')
.parse(process.argv)
if (program['video'] === undefined || program['import'] === undefined) {
const options = program.opts()
if (options.video === undefined || options.import === undefined) {
console.error('All parameters are mandatory.')
process.exit(-1)
}
@ -28,13 +30,13 @@ run()
async function run () {
await initDatabaseModels(true)
const video = await VideoModel.loadByUUID(program['video'])
const video = await VideoModel.loadByUUID(options.video)
if (!video) throw new Error('Video not found.')
if (video.isOwned() === false) throw new Error('Cannot import files of a non owned video.')
const dataInput = {
videoUUID: video.uuid,
filePath: resolve(program['import'])
filePath: resolve(options.import)
}
await JobQueue.Instance.init()

View File

@ -14,12 +14,14 @@ program
.option('--generate-hls', 'Generate HLS playlist')
.parse(process.argv)
if (program['video'] === undefined) {
const options = program.opts()
if (options.video === undefined) {
console.error('All parameters are mandatory.')
process.exit(-1)
}
if (program.resolution !== undefined && Number.isNaN(+program.resolution)) {
if (options.resolution !== undefined && Number.isNaN(+options.resolution)) {
console.error('The resolution must be an integer (example: 1080).')
process.exit(-1)
}
@ -34,15 +36,15 @@ run()
async function run () {
await initDatabaseModels(true)
const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(program['video'])
const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(options.video)
if (!video) throw new Error('Video not found.')
const dataInput: VideoTranscodingPayload[] = []
const { videoFileResolution } = await video.getMaxQualityResolution()
if (program.generateHls) {
const resolutionsEnabled = program.resolution
? [ program.resolution ]
if (options.generateHls) {
const resolutionsEnabled = options.resolution
? [ options.resolution ]
: computeResolutionsToTranscode(videoFileResolution, 'vod').concat([ videoFileResolution ])
for (const resolution of resolutionsEnabled) {
@ -54,12 +56,12 @@ async function run () {
copyCodecs: false
})
}
} else if (program.resolution !== undefined) {
} else if (options.resolution !== undefined) {
dataInput.push({
type: 'new-resolution-to-webtorrent',
videoUUID: video.uuid,
isNewVideo: false,
resolution: program.resolution
resolution: options.resolution
})
} else {
dataInput.push({

View File

@ -17,6 +17,8 @@ program
.option('-f, --files [file...]', 'Files to parse. If not provided, the script will parse the latest log file from config)')
.parse(process.argv)
const options = program.opts()
const excludedKeys = {
level: true,
message: true,
@ -38,7 +40,7 @@ const loggerFormat = winston.format.printf((info) => {
if (CONFIG.LOG.PRETTIFY_SQL) {
additionalInfos += '\n' + sqlFormat(info.sql, {
language: 'sql',
ident: ' '
indent: ' '
})
} else {
additionalInfos += ' - ' + info.sql
@ -51,7 +53,7 @@ const loggerFormat = winston.format.printf((info) => {
const logger = winston.createLogger({
transports: [
new winston.transports.Console({
level: program['level'] || 'debug',
level: options.level || 'debug',
stderrLevels: [],
format: winston.format.combine(
winston.format.splat(),
@ -76,7 +78,7 @@ run()
.catch(err => console.error(err))
function run () {
return new Promise(async res => {
return new Promise<void>(async res => {
const files = await getFiles()
for (const file of files) {
@ -114,7 +116,7 @@ async function getNewestFile (files: string[], basePath: string) {
}
async function getFiles () {
if (program['files']) return program['files']
if (options.files) return options.files
const logFiles = await readdir(CONFIG.STORAGE.LOG_DIR)

View File

@ -12,12 +12,14 @@ program
.option('-p, --plugin-path [pluginPath]', 'Path of the plugin you want to install')
.parse(process.argv)
if (!program['npmName'] && !program['pluginPath']) {
const options = program.opts()
if (!options.npmName && !options.pluginPath) {
console.error('You need to specify a plugin name with the desired version, or a plugin path.')
process.exit(-1)
}
if (program['pluginPath'] && !isAbsolute(program['pluginPath'])) {
if (options.pluginPath && !isAbsolute(options.pluginPath)) {
console.error('Plugin path should be absolute.')
process.exit(-1)
}
@ -32,6 +34,6 @@ run()
async function run () {
await initDatabaseModels(true)
const toInstall = program['npmName'] || program['pluginPath']
await PluginManager.Instance.install(toInstall, program['pluginVersion'], !!program['pluginPath'])
const toInstall = options.npmName || options.pluginPath
await PluginManager.Instance.install(toInstall, options.pluginVersion, !!options.pluginPath)
}

View File

@ -9,7 +9,9 @@ program
.option('-n, --npm-name [npmName]', 'Package name to install')
.parse(process.argv)
if (!program['npmName']) {
const options = program.opts()
if (!options.npmName) {
console.error('You need to specify the plugin name.')
process.exit(-1)
}
@ -25,6 +27,6 @@ async function run () {
await initDatabaseModels(true)
const toUninstall = program['npmName']
const toUninstall = options.npmName
await PluginManager.Instance.uninstall(toUninstall)
}

View File

@ -10,14 +10,16 @@ program
.option('-u, --user [user]', 'User')
.parse(process.argv)
if (program['user'] === undefined) {
const options = program.opts()
if (options.user === undefined) {
console.error('All parameters are mandatory.')
process.exit(-1)
}
initDatabaseModels(true)
.then(() => {
return UserModel.loadByUsername(program['user'])
return UserModel.loadByUsername(options.user)
})
.then(user => {
if (!user) {
@ -28,7 +30,7 @@ initDatabaseModels(true)
const readline = require('readline')
const Writable = require('stream').Writable
const mutableStdout = new Writable({
write: function (chunk, encoding, callback) {
write: function (_chunk, _encoding, callback) {
callback()
}
})

View File

@ -205,7 +205,8 @@ app.use('/', staticRouter)
app.use('/', lazyStaticRouter)
// Client files, last valid routes!
if (cli.client) app.use('/', clientsRouter)
const cliOptions = cli.opts()
if (cliOptions.client) app.use('/', clientsRouter)
// ----------- Errors -----------
@ -277,7 +278,7 @@ async function startApplication () {
updateStreamingPlaylistsInfohashesIfNeeded()
.catch(err => logger.error('Cannot update streaming playlist infohashes.', { err }))
if (cli.plugins) await PluginManager.Instance.registerPluginsAndThemes()
if (cliOptions.plugins) await PluginManager.Instance.registerPluginsAndThemes()
LiveManager.Instance.init()
if (CONFIG.LIVE.ENABLED) LiveManager.Instance.run()

View File

@ -30,7 +30,7 @@ export {
// ---------------------------------------------------------------------------
function convertSrtToVtt (source: string, destination: string) {
return new Promise((res, rej) => {
return new Promise<void>((res, rej) => {
const file = createReadStream(source)
const converter = srt2vtt()
const writer = createWriteStream(destination)

View File

@ -5,12 +5,12 @@
Useful to avoid circular dependencies.
*/
import { createHash, HexBase64Latin1Encoding, randomBytes } from 'crypto'
import { exec, ExecOptions } from 'child_process'
import { BinaryToTextEncoding, createHash, randomBytes } from 'crypto'
import { truncate } from 'lodash'
import { basename, isAbsolute, join, resolve } from 'path'
import * as pem from 'pem'
import { URL } from 'url'
import { truncate } from 'lodash'
import { exec, ExecOptions } from 'child_process'
const objectConverter = (oldObject: any, keyConverter: (e: string) => string, valueConverter: (e: any) => any) => {
if (!oldObject || typeof oldObject !== 'object') {
@ -205,11 +205,11 @@ function peertubeTruncate (str: string, options: { length: number, separator?: R
return truncate(str, options)
}
function sha256 (str: string | Buffer, encoding: HexBase64Latin1Encoding = 'hex') {
function sha256 (str: string | Buffer, encoding: BinaryToTextEncoding = 'hex') {
return createHash('sha256').update(str).digest(encoding)
}
function sha1 (str: string | Buffer, encoding: HexBase64Latin1Encoding = 'hex') {
function sha1 (str: string | Buffer, encoding: BinaryToTextEncoding = 'hex') {
return createHash('sha1').update(str).digest(encoding)
}

View File

@ -76,6 +76,7 @@ const lru = new AsyncLRU({
}
})
/* eslint-disable no-import-assign */
jsonld.documentLoader = (url) => {
return new Promise((res, rej) => {
lru.get(url, (err, value) => {

View File

@ -61,7 +61,7 @@ const consoleLoggerFormat = winston.format.printf(info => {
if (CONFIG.LOG.PRETTIFY_SQL) {
additionalInfos += '\n' + sqlFormat(info.sql, {
language: 'sql',
ident: ' '
indent: ' '
})
} else {
additionalInfos += ' - ' + info.sql

View File

@ -149,7 +149,7 @@ function safeWebtorrentDestroy (
downloadedFile?: { directoryPath: string, filepath: string },
torrentName?: string
) {
return new Promise(res => {
return new Promise<void>(res => {
webtorrent.destroy(err => {
// Delete torrent file
if (torrentName) {

View File

@ -195,7 +195,7 @@ async function updateYoutubeDLBinary () {
await ensureDir(binDirectory)
return new Promise(res => {
return new Promise<void>(res => {
request.get(url, { followRedirect: false }, (err, result) => {
if (err) {
logger.error('Cannot update youtube-dl.', { err })

View File

@ -41,6 +41,7 @@ class InboxManager {
addInboxMessage (options: QueueParam) {
this.inboxQueue.push(options)
.catch(err => logger.error('Cannot add options in inbox queue.', { options, err }))
}
static get Instance () {

View File

@ -65,7 +65,7 @@ const downloadImageQueue = queue<DownloadImageQueueTask, Error>((task, cb) => {
}, QUEUE_CONCURRENCY.AVATAR_PROCESS_IMAGE)
function pushAvatarProcessInQueue (task: DownloadImageQueueTask) {
return new Promise((res, rej) => {
return new Promise<void>((res, rej) => {
downloadImageQueue.push(task, err => {
if (err) return rej(err)

View File

@ -111,7 +111,7 @@ function downloadPlaylistSegments (playlistUrl: string, destinationDir: string,
logger.info('Importing HLS playlist %s', playlistUrl)
return new Promise<string>(async (res, rej) => {
return new Promise<void>(async (res, rej) => {
const tmpDirectory = join(CONFIG.STORAGE.TMP_DIR, await generateRandomString(10))
await ensureDir(tmpDirectory)

View File

@ -263,7 +263,7 @@ class Redis {
}
private addToSet (key: string, value: string) {
return new Promise<string[]>((res, rej) => {
return new Promise<void>((res, rej) => {
this.client.sadd(this.prefix + key, value, err => err ? rej(err) : res())
})
}

View File

@ -1,12 +1,13 @@
import { eachSeries } from 'async'
import { NextFunction, Request, RequestHandler, Response } from 'express'
import { retryTransactionWrapper } from '../helpers/database-utils'
import { ValidationChain } from 'express-validator'
import { ExpressPromiseHandler } from '@server/types/express'
import { retryTransactionWrapper } from '../helpers/database-utils'
// Syntactic sugar to avoid try/catch in express controllers
// Thanks: https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016
export type RequestPromiseHandler = ValidationChain | ((req: Request, res: Response, next: NextFunction) => Promise<any>)
export type RequestPromiseHandler = ValidationChain | ExpressPromiseHandler
function asyncMiddleware (fun: RequestPromiseHandler | RequestPromiseHandler[]) {
return (req: Request, res: Response, next: NextFunction) => {

View File

@ -49,7 +49,7 @@ function authenticateSocket (socket: Socket, next: (err?: any) => void) {
}
function authenticatePromiseIfNeeded (req: express.Request, res: express.Response, authenticateInQuery = false) {
return new Promise(resolve => {
return new Promise<void>(resolve => {
// Already authenticated? (or tried to)
if (res.locals.oauth?.token.User) return resolve()

View File

@ -14,7 +14,7 @@ import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-code
const startVideoPlaylistsURL = WEBSERVER.SCHEME + '://' + join(WEBSERVER.HOST, 'videos', 'watch', 'playlist') + '/'
const startVideosURL = WEBSERVER.SCHEME + '://' + join(WEBSERVER.HOST, 'videos', 'watch') + '/'
const watchRegex = new RegExp('([^/]+)$')
const watchRegex = /([^/]+)$/
const isURLOptions = {
require_host: true,
require_tld: true

View File

@ -1,10 +1,11 @@
import * as express from 'express'
import { body, param, query, ValidationChain } from 'express-validator'
import { ExpressPromiseHandler } from '@server/types/express'
import { MUserAccountId } from '@server/types/models'
import { UserRight, VideoPlaylistCreate, VideoPlaylistUpdate } from '../../../../shared'
import { logger } from '../../../helpers/logger'
import { areValidationErrors } from '../utils'
import { isVideoImage } from '../../../helpers/custom-validators/videos'
import { CONSTRAINTS_FIELDS } from '../../../initializers/constants'
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
import {
isArrayOf,
isIdOrUUIDValid,
@ -21,15 +22,15 @@ import {
isVideoPlaylistTimestampValid,
isVideoPlaylistTypeValid
} from '../../../helpers/custom-validators/video-playlists'
import { isVideoImage } from '../../../helpers/custom-validators/videos'
import { cleanUpReqFiles } from '../../../helpers/express-utils'
import { VideoPlaylistElementModel } from '../../../models/video/video-playlist-element'
import { authenticatePromiseIfNeeded } from '../../oauth'
import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
import { logger } from '../../../helpers/logger'
import { doesVideoChannelIdExist, doesVideoExist, doesVideoPlaylistExist, VideoPlaylistFetchType } from '../../../helpers/middlewares'
import { CONSTRAINTS_FIELDS } from '../../../initializers/constants'
import { VideoPlaylistElementModel } from '../../../models/video/video-playlist-element'
import { MVideoPlaylist } from '../../../types/models/video/video-playlist'
import { MUserAccountId } from '@server/types/models'
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
import { authenticatePromiseIfNeeded } from '../../oauth'
import { areValidationErrors } from '../utils'
const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([
body('displayName')
@ -395,7 +396,7 @@ function getCommonPlaylistEditAttributes () {
body('videoChannelId')
.optional()
.customSanitizer(toIntOrNull)
] as (ValidationChain | express.Handler)[]
] as (ValidationChain | ExpressPromiseHandler)[]
}
function checkUserCanManageVideoPlaylist (user: MUserAccountId, videoPlaylist: MVideoPlaylist, right: UserRight, res: express.Response) {

View File

@ -2,8 +2,10 @@ import * as express from 'express'
import { body, param, query, ValidationChain } from 'express-validator'
import { isAbleToUploadVideo } from '@server/lib/user'
import { getServerActor } from '@server/models/application/application'
import { ExpressPromiseHandler } from '@server/types/express'
import { MVideoFullLight } from '@server/types/models'
import { ServerErrorCode, UserRight, VideoChangeOwnershipStatus, VideoPrivacy } from '../../../../shared'
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
import { VideoChangeOwnershipAccept } from '../../../../shared/models/videos/video-change-ownership-accept.model'
import {
exists,
@ -54,7 +56,6 @@ import { AccountModel } from '../../../models/account/account'
import { VideoModel } from '../../../models/video/video'
import { authenticatePromiseIfNeeded } from '../../oauth'
import { areValidationErrors } from '../utils'
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const videosAddValidator = getCommonVideoEditAttributes().concat([
body('videofile')
@ -411,7 +412,7 @@ function getCommonVideoEditAttributes () {
.optional()
.customSanitizer(toIntOrNull)
.custom(isScheduleVideoUpdatePrivacyValid).withMessage('Should have correct schedule update privacy')
] as (ValidationChain | express.Handler)[]
] as (ValidationChain | ExpressPromiseHandler)[]
}
const commonVideosFiltersValidator = [

View File

@ -469,27 +469,33 @@ export class UserNotificationModel extends Model {
? Object.assign(this.formatVideo(this.Video), { channel: this.formatActor(this.Video.VideoChannel) })
: undefined
const videoImport = this.VideoImport ? {
id: this.VideoImport.id,
video: this.VideoImport.Video ? this.formatVideo(this.VideoImport.Video) : undefined,
torrentName: this.VideoImport.torrentName,
magnetUri: this.VideoImport.magnetUri,
targetUrl: this.VideoImport.targetUrl
} : undefined
const videoImport = this.VideoImport
? {
id: this.VideoImport.id,
video: this.VideoImport.Video ? this.formatVideo(this.VideoImport.Video) : undefined,
torrentName: this.VideoImport.torrentName,
magnetUri: this.VideoImport.magnetUri,
targetUrl: this.VideoImport.targetUrl
}
: undefined
const comment = this.Comment ? {
id: this.Comment.id,
threadId: this.Comment.getThreadId(),
account: this.formatActor(this.Comment.Account),
video: this.formatVideo(this.Comment.Video)
} : undefined
const comment = this.Comment
? {
id: this.Comment.id,
threadId: this.Comment.getThreadId(),
account: this.formatActor(this.Comment.Account),
video: this.formatVideo(this.Comment.Video)
}
: undefined
const abuse = this.Abuse ? this.formatAbuse(this.Abuse) : undefined
const videoBlacklist = this.VideoBlacklist ? {
id: this.VideoBlacklist.id,
video: this.formatVideo(this.VideoBlacklist.Video)
} : undefined
const videoBlacklist = this.VideoBlacklist
? {
id: this.VideoBlacklist.id,
video: this.formatVideo(this.VideoBlacklist.Video)
}
: undefined
const account = this.Account ? this.formatActor(this.Account) : undefined
@ -498,23 +504,25 @@ export class UserNotificationModel extends Model {
Group: 'channel' as 'channel',
Person: 'account' as 'account'
}
const actorFollow = this.ActorFollow ? {
id: this.ActorFollow.id,
state: this.ActorFollow.state,
follower: {
id: this.ActorFollow.ActorFollower.Account.id,
displayName: this.ActorFollow.ActorFollower.Account.getDisplayName(),
name: this.ActorFollow.ActorFollower.preferredUsername,
avatar: this.ActorFollow.ActorFollower.Avatar ? { path: this.ActorFollow.ActorFollower.Avatar.getStaticPath() } : undefined,
host: this.ActorFollow.ActorFollower.getHost()
},
following: {
type: actorFollowingType[this.ActorFollow.ActorFollowing.type],
displayName: (this.ActorFollow.ActorFollowing.VideoChannel || this.ActorFollow.ActorFollowing.Account).getDisplayName(),
name: this.ActorFollow.ActorFollowing.preferredUsername,
host: this.ActorFollow.ActorFollowing.getHost()
const actorFollow = this.ActorFollow
? {
id: this.ActorFollow.id,
state: this.ActorFollow.state,
follower: {
id: this.ActorFollow.ActorFollower.Account.id,
displayName: this.ActorFollow.ActorFollower.Account.getDisplayName(),
name: this.ActorFollow.ActorFollower.preferredUsername,
avatar: this.ActorFollow.ActorFollower.Avatar ? { path: this.ActorFollow.ActorFollower.Avatar.getStaticPath() } : undefined,
host: this.ActorFollow.ActorFollower.getHost()
},
following: {
type: actorFollowingType[this.ActorFollow.ActorFollowing.type],
displayName: (this.ActorFollow.ActorFollowing.VideoChannel || this.ActorFollow.ActorFollowing.Account).getDisplayName(),
name: this.ActorFollow.ActorFollowing.preferredUsername,
host: this.ActorFollow.ActorFollowing.getHost()
}
}
} : undefined
: undefined
return {
id: this.id,
@ -541,15 +549,17 @@ export class UserNotificationModel extends Model {
}
formatAbuse (this: UserNotificationModelForApi, abuse: UserNotificationIncludes.AbuseInclude) {
const commentAbuse = abuse.VideoCommentAbuse?.VideoComment ? {
threadId: abuse.VideoCommentAbuse.VideoComment.getThreadId(),
const commentAbuse = abuse.VideoCommentAbuse?.VideoComment
? {
threadId: abuse.VideoCommentAbuse.VideoComment.getThreadId(),
video: {
id: abuse.VideoCommentAbuse.VideoComment.Video.id,
name: abuse.VideoCommentAbuse.VideoComment.Video.name,
uuid: abuse.VideoCommentAbuse.VideoComment.Video.uuid
video: {
id: abuse.VideoCommentAbuse.VideoComment.Video.id,
name: abuse.VideoCommentAbuse.VideoComment.Video.name,
uuid: abuse.VideoCommentAbuse.VideoComment.Video.uuid
}
}
} : undefined
: undefined
const videoAbuse = abuse.VideoAbuse?.Video ? this.formatVideo(abuse.VideoAbuse.Video) : undefined

View File

@ -82,9 +82,9 @@ function videoModelToFormattedJSON (video: MVideoFormattable, options?: VideoFor
account: video.VideoChannel.Account.toFormattedSummaryJSON(),
channel: video.VideoChannel.toFormattedSummaryJSON(),
userHistory: userHistory ? {
currentTime: userHistory.currentTime
} : undefined,
userHistory: userHistory
? { currentTime: userHistory.currentTime }
: undefined,
// Can be added by external plugins
pluginData: (video as any).pluginData

View File

@ -69,23 +69,25 @@ function deleteSettings () {
}
function getRemoteObjectOrDie (
program: any,
program: CommanderStatic,
settings: Settings,
netrc: Netrc
): { url: string, username: string, password: string } {
if (!program['url'] || !program['username'] || !program['password']) {
const options = program.opts()
if (!options.url || !options.username || !options.password) {
// No remote and we don't have program parameters: quit
if (settings.remotes.length === 0 || Object.keys(netrc.machines).length === 0) {
if (!program['url']) console.error('--url field is required.')
if (!program['username']) console.error('--username field is required.')
if (!program['password']) console.error('--password field is required.')
if (!options.url) console.error('--url field is required.')
if (!options.username) console.error('--username field is required.')
if (!options.password) console.error('--password field is required.')
return process.exit(-1)
}
let url: string = program['url']
let username: string = program['username']
let password: string = program['password']
let url: string = options.url
let username: string = options.username
let password: string = options.password
if (!url && settings.default !== -1) url = settings.remotes[settings.default]
@ -98,9 +100,9 @@ function getRemoteObjectOrDie (
}
return {
url: program['url'],
username: program['username'],
password: program['password']
url: options.url,
username: options.username,
password: options.password
}
}
@ -127,6 +129,8 @@ function buildCommonVideoOptions (command: CommanderStatic) {
}
async function buildVideoAttributesFromCommander (url: string, command: CommanderStatic, defaultAttributes: any = {}) {
const options = command.opts()
const defaultBooleanAttributes = {
nsfw: false,
commentsEnabled: true,
@ -137,8 +141,8 @@ async function buildVideoAttributesFromCommander (url: string, command: Commande
const booleanAttributes: { [id in keyof typeof defaultBooleanAttributes]: boolean } | {} = {}
for (const key of Object.keys(defaultBooleanAttributes)) {
if (command[key] !== undefined) {
booleanAttributes[key] = command[key]
if (options[key] !== undefined) {
booleanAttributes[key] = options[key]
} else if (defaultAttributes[key] !== undefined) {
booleanAttributes[key] = defaultAttributes[key]
} else {
@ -147,20 +151,20 @@ async function buildVideoAttributesFromCommander (url: string, command: Commande
}
const videoAttributes = {
name: command['videoName'] || defaultAttributes.name,
category: command['category'] || defaultAttributes.category || undefined,
licence: command['licence'] || defaultAttributes.licence || undefined,
language: command['language'] || defaultAttributes.language || undefined,
privacy: command['privacy'] || defaultAttributes.privacy || VideoPrivacy.PUBLIC,
support: command['support'] || defaultAttributes.support || undefined,
description: command['videoDescription'] || defaultAttributes.description || undefined,
tags: command['tags'] || defaultAttributes.tags || undefined
name: options.videoName || defaultAttributes.name,
category: options.category || defaultAttributes.category || undefined,
licence: options.licence || defaultAttributes.licence || undefined,
language: options.language || defaultAttributes.language || undefined,
privacy: options.privacy || defaultAttributes.privacy || VideoPrivacy.PUBLIC,
support: options.support || defaultAttributes.support || undefined,
description: options.videoDescription || defaultAttributes.description || undefined,
tags: options.tags || defaultAttributes.tags || undefined
}
Object.assign(videoAttributes, booleanAttributes)
if (command['channelName']) {
const res = await getVideoChannel(url, command['channelName'])
if (options.channelName) {
const res = await getVideoChannel(url, options.channelName)
const videoChannel: VideoChannel = res.body
Object.assign(videoAttributes, { channelId: videoChannel.id })
@ -173,7 +177,7 @@ async function buildVideoAttributesFromCommander (url: string, command: Commande
return videoAttributes
}
function getServerCredentials (program: any) {
function getServerCredentials (program: CommanderStatic) {
return Promise.all([ getSettings(), getNetrc() ])
.then(([ settings, netrc ]) => {
return getRemoteObjectOrDie(program, settings, netrc)

View File

@ -66,7 +66,8 @@ program
.option('-U, --username <username>', 'Username')
.option('-p, --password <token>', 'Password')
.option('--default', 'add the entry as the new default')
.action(options => {
.action((options: program.OptionValues) => {
/* eslint-disable no-import-assign */
prompt.override = options
prompt.start()
prompt.get({
@ -102,7 +103,7 @@ program
process.exit(-1)
}
await setInstance(result.url, result.username, result.password, program['default'])
await setInstance(result.url, result.username, result.password, options.default)
process.exit(0)
})
@ -160,15 +161,12 @@ program
}
})
program.on('--help', function () {
console.log(' Examples:')
console.log()
console.log(' $ peertube auth add -u https://peertube.cpy.re -U "PEERTUBE_USER" --password "PEERTUBE_PASSWORD"')
console.log(' $ peertube auth add -u https://peertube.cpy.re -U root')
console.log(' $ peertube auth list')
console.log(' $ peertube auth del https://peertube.cpy.re')
console.log()
})
program.addHelpText('after', '\n\n Examples:\n\n' +
' $ peertube auth add -u https://peertube.cpy.re -U "PEERTUBE_USER" --password "PEERTUBE_PASSWORD"\n' +
' $ peertube auth add -u https://peertube.cpy.re -U root\n' +
' $ peertube auth list\n' +
' $ peertube auth del https://peertube.cpy.re\n'
)
if (!process.argv.slice(2).length) {
program.outputHelp()

View File

@ -10,25 +10,27 @@ program
.option('-p, --password <token>', 'Password')
.parse(process.argv)
const options = program.opts()
if (
!program['url'] ||
!program['username'] ||
!program['password']
!options.url ||
!options.username ||
!options.password
) {
if (!program['url']) console.error('--url field is required.')
if (!program['username']) console.error('--username field is required.')
if (!program['password']) console.error('--password field is required.')
if (!options.url) console.error('--url field is required.')
if (!options.username) console.error('--username field is required.')
if (!options.password) console.error('--password field is required.')
process.exit(-1)
}
getClient(program.url)
getClient(options.url)
.then(res => {
const server = {
url: program['url'],
url: options.url,
user: {
username: program['username'],
password: program['password']
username: options.username,
password: options.password
},
client: {
id: res.body.client_id,

View File

@ -45,22 +45,24 @@ command
.usage("[global options] [ -- youtube-dl options]")
.parse(process.argv)
const log = getLogger(program['verbose'])
const options = command.opts()
const log = getLogger(options.verbose)
getServerCredentials(command)
.then(({ url, username, password }) => {
if (!program['targetUrl']) {
if (!options.targetUrl) {
exitError('--target-url field is required.')
}
try {
accessSync(program['tmpdir'], constants.R_OK | constants.W_OK)
accessSync(options.tmpdir, constants.R_OK | constants.W_OK)
} catch (e) {
exitError('--tmpdir %s: directory does not exist or is not accessible', program['tmpdir'])
exitError('--tmpdir %s: directory does not exist or is not accessible', options.tmpdir)
}
url = normalizeTargetUrl(url)
program['targetUrl'] = normalizeTargetUrl(program['targetUrl'])
options.targetUrl = normalizeTargetUrl(options.targetUrl)
const user = { username, password }
@ -76,7 +78,7 @@ async function run (url: string, user: UserInfo) {
const youtubeDL = await safeGetYoutubeDL()
let info = await getYoutubeDLInfo(youtubeDL, program['targetUrl'], command.args)
let info = await getYoutubeDLInfo(youtubeDL, options.targetUrl, command.args)
if (!Array.isArray(info)) info = [ info ]
@ -92,10 +94,10 @@ async function run (url: string, user: UserInfo) {
let infoArray: any[]
infoArray = [].concat(info)
if (program['first']) {
infoArray = infoArray.slice(0, program['first'])
} else if (program['last']) {
infoArray = infoArray.slice(-program['last'])
if (options.first) {
infoArray = infoArray.slice(0, options.first)
} else if (options.last) {
infoArray = infoArray.slice(-options.last)
}
// Normalize utf8 fields
infoArray = infoArray.map(i => normalizeObject(i))
@ -104,12 +106,12 @@ async function run (url: string, user: UserInfo) {
for (const [ index, info ] of infoArray.entries()) {
try {
if (index > 0 && program['waitInterval']) {
log.info("Wait for %d seconds before continuing.", program['waitInterval'] / 1000)
await new Promise(res => setTimeout(res, program['waitInterval']))
if (index > 0 && options.waitInterval) {
log.info("Wait for %d seconds before continuing.", options.waitInterval / 1000)
await new Promise(res => setTimeout(res, options.waitInterval))
}
await processVideo({
cwd: program['tmpdir'],
cwd: options.tmpdir,
url,
user,
youtubeInfo: info
@ -119,7 +121,7 @@ async function run (url: string, user: UserInfo) {
}
}
log.info('Video/s for user %s imported: %s', user.username, program['targetUrl'])
log.info('Video/s for user %s imported: %s', user.username, options.targetUrl)
process.exit(0)
}
@ -137,14 +139,14 @@ async function processVideo (parameters: {
log.debug('Fetched object.', videoInfo)
const originallyPublishedAt = buildOriginallyPublishedAt(videoInfo)
if (program['since'] && originallyPublishedAt && originallyPublishedAt.getTime() < program['since'].getTime()) {
if (options.since && originallyPublishedAt && originallyPublishedAt.getTime() < options.since.getTime()) {
log.info('Video "%s" has been published before "%s", don\'t upload it.\n',
videoInfo.title, formatDate(program['since']))
videoInfo.title, formatDate(options.since))
return
}
if (program['until'] && originallyPublishedAt && originallyPublishedAt.getTime() > program['until'].getTime()) {
if (options.until && originallyPublishedAt && originallyPublishedAt.getTime() > options.until.getTime()) {
log.info('Video "%s" has been published after "%s", don\'t upload it.\n',
videoInfo.title, formatDate(program['until']))
videoInfo.title, formatDate(options.until))
return
}
@ -161,11 +163,11 @@ async function processVideo (parameters: {
log.info('Downloading video "%s"...', videoInfo.title)
const options = [ '-f', getYoutubeDLVideoFormat(), ...command.args, '-o', path ]
const youtubeDLOptions = [ '-f', getYoutubeDLVideoFormat(), ...command.args, '-o', path ]
try {
const youtubeDL = await safeGetYoutubeDL()
const youtubeDLExec = promisify(youtubeDL.exec).bind(youtubeDL)
const output = await youtubeDLExec(videoInfo.url, options, processOptions)
const output = await youtubeDLExec(videoInfo.url, youtubeDLOptions, processOptions)
log.info(output.join('\n'))
await uploadVideoOnPeerTube({
cwd,

View File

@ -10,6 +10,7 @@ import { getAdminTokenOrDie, getServerCredentials } from './cli'
import { PeerTubePlugin } from '../../shared/models/plugins/peertube-plugin.model'
import { isAbsolute } from 'path'
import * as CliTable3 from 'cli-table3'
import commander = require('commander')
program
.name('plugins')
@ -33,7 +34,7 @@ program
.option('-p, --password <token>', 'Password')
.option('-P --path <path>', 'Install from a path')
.option('-n, --npm-name <npmName>', 'Install from npm')
.action((options) => installPluginCLI(options))
.action((options, command) => installPluginCLI(command, options))
program
.command('update')
@ -43,7 +44,7 @@ program
.option('-p, --password <token>', 'Password')
.option('-P --path <path>', 'Update from a path')
.option('-n, --npm-name <npmName>', 'Update from npm')
.action((options) => updatePluginCLI(options))
.action((options, command) => updatePluginCLI(command, options))
program
.command('uninstall')
@ -52,7 +53,7 @@ program
.option('-U, --username <username>', 'Username')
.option('-p, --password <token>', 'Password')
.option('-n, --npm-name <npmName>', 'NPM plugin/theme name')
.action(options => uninstallPluginCLI(options))
.action((options, command) => uninstallPluginCLI(command, options))
if (!process.argv.slice(2).length) {
program.outputHelp()
@ -60,6 +61,8 @@ if (!process.argv.slice(2).length) {
program.parse(process.argv)
const options = program.opts()
// ----------------------------------------------------------------------------
async function pluginsListCLI () {
@ -67,8 +70,8 @@ async function pluginsListCLI () {
const accessToken = await getAdminTokenOrDie(url, username, password)
let pluginType: PluginType
if (program['onlyThemes']) pluginType = PluginType.THEME
if (program['onlyPlugins']) pluginType = PluginType.PLUGIN
if (options.onlyThemes) pluginType = PluginType.THEME
if (options.onlyPlugins) pluginType = PluginType.PLUGIN
const res = await listPlugins({
url,
@ -101,27 +104,27 @@ async function pluginsListCLI () {
process.exit(0)
}
async function installPluginCLI (options: any) {
if (!options['path'] && !options['npmName']) {
async function installPluginCLI (command: commander.CommanderStatic, options: commander.OptionValues) {
if (!options.path && !options.npmName) {
console.error('You need to specify the npm name or the path of the plugin you want to install.\n')
program.outputHelp()
process.exit(-1)
}
if (options['path'] && !isAbsolute(options['path'])) {
if (options.path && !isAbsolute(options.path)) {
console.error('Path should be absolute.')
process.exit(-1)
}
const { url, username, password } = await getServerCredentials(options)
const { url, username, password } = await getServerCredentials(command)
const accessToken = await getAdminTokenOrDie(url, username, password)
try {
await installPlugin({
url,
accessToken,
npmName: options['npmName'],
path: options['path']
npmName: options.npmName,
path: options.path
})
} catch (err) {
console.error('Cannot install plugin.', err)
@ -132,27 +135,27 @@ async function installPluginCLI (options: any) {
process.exit(0)
}
async function updatePluginCLI (options: any) {
if (!options['path'] && !options['npmName']) {
async function updatePluginCLI (command: commander.CommanderStatic, options: commander.OptionValues) {
if (!options.path && !options.npmName) {
console.error('You need to specify the npm name or the path of the plugin you want to update.\n')
program.outputHelp()
process.exit(-1)
}
if (options['path'] && !isAbsolute(options['path'])) {
if (options.path && !isAbsolute(options.path)) {
console.error('Path should be absolute.')
process.exit(-1)
}
const { url, username, password } = await getServerCredentials(options)
const { url, username, password } = await getServerCredentials(command)
const accessToken = await getAdminTokenOrDie(url, username, password)
try {
await updatePlugin({
url,
accessToken,
npmName: options['npmName'],
path: options['path']
npmName: options.npmName,
path: options.path
})
} catch (err) {
console.error('Cannot update plugin.', err)
@ -163,21 +166,21 @@ async function updatePluginCLI (options: any) {
process.exit(0)
}
async function uninstallPluginCLI (options: any) {
if (!options['npmName']) {
async function uninstallPluginCLI (command: commander.CommanderStatic, options: commander.OptionValues) {
if (!options.npmName) {
console.error('You need to specify the npm name of the plugin/theme you want to uninstall.\n')
program.outputHelp()
process.exit(-1)
}
const { url, username, password } = await getServerCredentials(options)
const { url, username, password } = await getServerCredentials(command)
const accessToken = await getAdminTokenOrDie(url, username, password)
try {
await uninstallPlugin({
url,
accessToken,
npmName: options['npmName']
npmName: options.npmName
})
} catch (err) {
console.error('Cannot uninstall plugin.', err)

View File

@ -14,6 +14,7 @@ import { URL } from 'url'
import { uniq } from 'lodash'
import bytes = require('bytes')
import commander = require('commander')
program
.name('plugins')
@ -42,7 +43,7 @@ program
.option('-U, --username <username>', 'Username')
.option('-p, --password <token>', 'Password')
.option('-v, --video <videoId>', 'Video id to duplicate')
.action((options) => addRedundancyCLI(options))
.action((options, command) => addRedundancyCLI(options, command))
program
.command('remove')
@ -51,7 +52,7 @@ program
.option('-U, --username <username>', 'Username')
.option('-p, --password <token>', 'Password')
.option('-v, --video <videoId>', 'Video id to remove from redundancies')
.action((options) => removeRedundancyCLI(options))
.action((options, command) => removeRedundancyCLI(options, command))
if (!process.argv.slice(2).length) {
program.outputHelp()
@ -104,13 +105,13 @@ async function listRedundanciesCLI (target: VideoRedundanciesTarget) {
process.exit(0)
}
async function addRedundancyCLI (options: { videoId: number }) {
const { url, username, password } = await getServerCredentials(program)
async function addRedundancyCLI (options: { video: number }, command: commander.CommanderStatic) {
const { url, username, password } = await getServerCredentials(command)
const accessToken = await getAdminTokenOrDie(url, username, password)
if (!options['video'] || validator.isInt('' + options['video']) === false) {
if (!options.video || validator.isInt('' + options.video) === false) {
console.error('You need to specify the video id to duplicate and it should be a number.\n')
program.outputHelp()
command.outputHelp()
process.exit(-1)
}
@ -118,7 +119,7 @@ async function addRedundancyCLI (options: { videoId: number }) {
await addVideoRedundancy({
url,
accessToken,
videoId: options['video']
videoId: options.video
})
console.log('Video will be duplicated by your instance!')
@ -137,17 +138,17 @@ async function addRedundancyCLI (options: { videoId: number }) {
}
}
async function removeRedundancyCLI (options: { videoId: number }) {
const { url, username, password } = await getServerCredentials(program)
async function removeRedundancyCLI (options: { video: number }, command: commander.CommanderStatic) {
const { url, username, password } = await getServerCredentials(command)
const accessToken = await getAdminTokenOrDie(url, username, password)
if (!options['video'] || validator.isInt('' + options['video']) === false) {
if (!options.video || validator.isInt('' + options.video) === false) {
console.error('You need to specify the video id to remove from your redundancies.\n')
program.outputHelp()
command.outputHelp()
process.exit(-1)
}
const videoId = parseInt(options['video'] + '', 10)
const videoId = parseInt(options.video + '', 10)
let redundancies = await listVideoRedundanciesData(url, accessToken, 'my-videos')
let videoRedundancy = redundancies.find(r => videoId === r.id)

View File

@ -82,7 +82,6 @@ const start = async () => {
}
replServer.defineCommand('reset', resetCommand)
replServer.defineCommand('r', resetCommand)
}
start()

View File

@ -22,16 +22,18 @@ command
.option('-f, --file <file>', 'Video absolute file path')
.parse(process.argv)
const options = command.opts()
getServerCredentials(command)
.then(({ url, username, password }) => {
if (!program['videoName'] || !program['file']) {
if (!program['videoName']) console.error('--video-name is required.')
if (!program['file']) console.error('--file is required.')
if (!options.videoName || !options.file) {
if (!options.videoName) console.error('--video-name is required.')
if (!options.file) console.error('--file is required.')
process.exit(-1)
}
if (isAbsolute(program['file']) === false) {
if (isAbsolute(options.file) === false) {
console.error('File path should be absolute.')
process.exit(-1)
}
@ -46,21 +48,21 @@ getServerCredentials(command)
async function run (url: string, username: string, password: string) {
const accessToken = await getAccessToken(url, username, password)
await access(program['file'], constants.F_OK)
await access(options.file, constants.F_OK)
console.log('Uploading %s video...', program['videoName'])
console.log('Uploading %s video...', options.videoName)
const videoAttributes = await buildVideoAttributesFromCommander(url, program)
Object.assign(videoAttributes, {
fixture: program['file'],
thumbnailfile: program['thumbnail'],
previewfile: program['preview']
fixture: options.file,
thumbnailfile: options.thumbnail,
previewfile: options.preview
})
try {
await uploadVideo(url, accessToken, videoAttributes)
console.log(`Video ${program['videoName']} uploaded.`)
console.log(`Video ${options.videoName} uploaded.`)
process.exit(0)
} catch (err) {
console.error(require('util').inspect(err))

View File

@ -8,40 +8,30 @@ import { execSync } from 'child_process'
program
.name('watch')
.arguments('<url>')
.option('-g, --gui <player>', 'player type', /^(airplay|stdout|chromecast|mpv|vlc|mplayer|xbmc)$/i, 'vlc')
.addOption(
new program.Option('-g, --gui <player>', 'player type')
.default('vlc')
.choices([ 'airplay', 'stdout', 'chromecast', 'mpv', 'vlc', 'mplayer', 'xbmc' ])
)
.option('-r, --resolution <res>', 'video resolution', '480')
.on('--help', function () {
console.log(' Available Players:')
console.log()
console.log(' - mpv')
console.log(' - mplayer')
console.log(' - vlc')
console.log(' - stdout')
console.log(' - xbmc')
console.log(' - airplay')
console.log(' - chromecast')
console.log()
console.log()
console.log(' Examples:')
console.log()
console.log(' $ peertube watch -g mpv https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10')
console.log(' $ peertube watch --gui stdout https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10')
console.log(' $ peertube watch https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10')
console.log()
})
.action((url, cmd) => run(url, cmd))
.addHelpText('after', '\n\n Examples:\n\n' +
' $ peertube watch -g mpv https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10\n' +
' $ peertube watch --gui stdout https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10\n' +
' $ peertube watch https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10\n'
)
.action((url, options) => run(url, options))
.parse(process.argv)
function run (url: string, program: any) {
function run (url: string, options: program.OptionValues) {
if (!url) {
console.error('<url> positional argument is required.')
process.exit(-1)
}
const cmd = 'node ' + join(__dirname, 'node_modules', 'webtorrent-hybrid', 'bin', 'cmd.js')
const args = ` --${program.gui} ` +
const args = ` --${options.gui} ` +
url.replace('videos/watch', 'download/torrents') +
`-${program.resolution}.torrent`
`-${options.resolution}.torrent`
try {
execSync(cmd + args)

View File

@ -69,17 +69,12 @@ getSettings()
: 'instance ' + settings.remotes[settings.default] + ' selected'
program
.on('--help', function () {
console.log()
console.log(' State: ' + state)
console.log()
console.log(' Examples:')
console.log()
console.log(' $ peertube auth add -u "PEERTUBE_URL" -U "PEERTUBE_USER" --password "PEERTUBE_PASSWORD"')
console.log(' $ peertube up <videoFile>')
console.log(' $ peertube watch https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10')
console.log()
})
.addHelpText('after', '\n\n State: ' + state + '\n\n' +
' Examples:\n\n' +
' $ peertube auth add -u "PEERTUBE_URL" -U "PEERTUBE_USER" --password "PEERTUBE_PASSWORD"\n' +
' $ peertube up <videoFile>\n' +
' $ peertube watch https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10\n'
)
.parse(process.argv)
})
.catch(err => console.error(err))

3
server/types/express.ts Normal file
View File

@ -0,0 +1,3 @@
import { NextFunction, Request, Response } from 'express'
export type ExpressPromiseHandler = (req: Request<any>, res: Response, next: NextFunction) => Promise<any>

View File

@ -4,7 +4,7 @@ export class MockInstancesIndex {
private readonly indexInstances: { host: string, createdAt: string }[] = []
initialize () {
return new Promise(res => {
return new Promise<void>(res => {
const app = express()
app.use('/', (req: express.Request, res: express.Response, next: express.NextFunction) => {

View File

@ -1,4 +1,5 @@
import { ChildProcess, fork } from 'child_process'
import { join } from 'path'
import { randomInt } from '../../core-utils/miscs/miscs'
import { parallelTests } from '../server/servers'
@ -10,7 +11,7 @@ class MockSmtpServer {
private emails: object[]
private constructor () {
this.emailChildProcess = fork(`${__dirname}/email-child-process`, [])
this.emailChildProcess = fork(join(__dirname, 'email-child-process'), [])
this.emailChildProcess.on('message', (msg: any) => {
if (msg.email) {
@ -27,7 +28,7 @@ class MockSmtpServer {
if (this.started) {
this.emails = emailsCollection
return res()
return res(undefined)
}
// ensure maildev isn't started until

View File

@ -21,19 +21,21 @@ function reportAbuse (options: {
}) {
const path = '/api/v1/abuses'
const video = options.videoId ? {
id: options.videoId,
startAt: options.startAt,
endAt: options.endAt
} : undefined
const video = options.videoId
? {
id: options.videoId,
startAt: options.startAt,
endAt: options.endAt
}
: undefined
const comment = options.commentId ? {
id: options.commentId
} : undefined
const comment = options.commentId
? { id: options.commentId }
: undefined
const account = options.accountId ? {
id: options.accountId
} : undefined
const account = options.accountId
? { id: options.accountId }
: undefined
const body = {
account,

View File

@ -14,7 +14,7 @@ export class MockBlocklist {
private server: Server
initialize () {
return new Promise(res => {
return new Promise<void>(res => {
const app = express()
app.get('/blocklist', (req: express.Request, res: express.Response) => {

View File

@ -98,7 +98,7 @@ function sendRTMPStream (rtmpBaseUrl: string, streamKey: string, fixtureName = '
}
function waitFfmpegUntilError (command: ffmpeg.FfmpegCommand, successAfterMS = 10000) {
return new Promise((res, rej) => {
return new Promise<void>((res, rej) => {
command.on('error', err => {
return rej(err)
})

2299
yarn.lock

File diff suppressed because it is too large Load Diff