diff options
-rw-r--r-- | server/controllers/api/video-playlist.ts | 10 | ||||
-rw-r--r-- | server/helpers/custom-validators/misc.ts | 2 | ||||
-rw-r--r-- | server/helpers/ffmpeg/ffmpeg-commons.ts | 2 | ||||
-rw-r--r-- | server/helpers/youtube-dl/youtube-dl-wrapper.ts | 2 | ||||
-rw-r--r-- | server/initializers/constants.ts | 2 | ||||
-rw-r--r-- | server/lib/activitypub/share.ts | 2 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/activitypub-cleaner.ts | 2 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-import.ts | 2 | ||||
-rw-r--r-- | server/lib/moderation.ts | 2 | ||||
-rw-r--r-- | server/lib/schedulers/plugins-check-scheduler.ts | 2 | ||||
-rw-r--r-- | server/middlewares/activitypub.ts | 2 | ||||
-rw-r--r-- | server/middlewares/validators/user-subscriptions.ts | 4 | ||||
-rw-r--r-- | server/models/abuse/abuse.ts | 2 | ||||
-rw-r--r-- | server/models/server/plugin.ts | 4 | ||||
-rw-r--r-- | server/models/video/formatter/video-format-utils.ts | 2 | ||||
-rw-r--r-- | server/models/video/sql/video/shared/abstract-video-query-builder.ts | 2 | ||||
-rw-r--r-- | server/tests/api/live/live-fast-restream.ts | 2 | ||||
-rw-r--r-- | shared/core-utils/i18n/i18n.ts | 2 | ||||
-rw-r--r-- | shared/server-commands/server/server.ts | 2 |
19 files changed, 28 insertions, 22 deletions
diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts index 67fac3751..f8a607170 100644 --- a/server/controllers/api/video-playlist.ts +++ b/server/controllers/api/video-playlist.ts | |||
@@ -4,6 +4,7 @@ import { scheduleRefreshIfNeeded } from '@server/lib/activitypub/playlists' | |||
4 | import { Hooks } from '@server/lib/plugins/hooks' | 4 | import { Hooks } from '@server/lib/plugins/hooks' |
5 | import { getServerActor } from '@server/models/application/application' | 5 | import { getServerActor } from '@server/models/application/application' |
6 | import { MVideoPlaylistFull, MVideoPlaylistThumbnail, MVideoThumbnail } from '@server/types/models' | 6 | import { MVideoPlaylistFull, MVideoPlaylistThumbnail, MVideoThumbnail } from '@server/types/models' |
7 | import { forceNumber } from '@shared/core-utils' | ||
7 | import { uuidToShort } from '@shared/extra-utils' | 8 | import { uuidToShort } from '@shared/extra-utils' |
8 | import { VideoPlaylistCreateResult, VideoPlaylistElementCreateResult } from '@shared/models' | 9 | import { VideoPlaylistCreateResult, VideoPlaylistElementCreateResult } from '@shared/models' |
9 | import { HttpStatusCode } from '../../../shared/models/http/http-error-codes' | 10 | import { HttpStatusCode } from '../../../shared/models/http/http-error-codes' |
@@ -46,7 +47,6 @@ import { | |||
46 | import { AccountModel } from '../../models/account/account' | 47 | import { AccountModel } from '../../models/account/account' |
47 | import { VideoPlaylistModel } from '../../models/video/video-playlist' | 48 | import { VideoPlaylistModel } from '../../models/video/video-playlist' |
48 | import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element' | 49 | import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element' |
49 | import { forceNumber } from '@shared/core-utils' | ||
50 | 50 | ||
51 | const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT) | 51 | const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT) |
52 | 52 | ||
@@ -425,7 +425,13 @@ async function reorderVideosPlaylist (req: express.Request, res: express.Respons | |||
425 | 425 | ||
426 | const endOldPosition = oldPosition + reorderLength - 1 | 426 | const endOldPosition = oldPosition + reorderLength - 1 |
427 | // Insert our reordered elements in their place (update) | 427 | // Insert our reordered elements in their place (update) |
428 | await VideoPlaylistElementModel.reassignPositionOf({ videoPlaylistId: videoPlaylist.id, firstPosition: oldPosition, endPosition: endOldPosition, newPosition, transaction: t }) | 428 | await VideoPlaylistElementModel.reassignPositionOf({ |
429 | videoPlaylistId: videoPlaylist.id, | ||
430 | firstPosition: oldPosition, | ||
431 | endPosition: endOldPosition, | ||
432 | newPosition, | ||
433 | transaction: t | ||
434 | }) | ||
429 | 435 | ||
430 | // Decrease positions of elements after the old position of our ordered elements (decrease) | 436 | // Decrease positions of elements after the old position of our ordered elements (decrease) |
431 | await VideoPlaylistElementModel.increasePositionOf(videoPlaylist.id, oldPosition, -reorderLength, t) | 437 | await VideoPlaylistElementModel.increasePositionOf(videoPlaylist.id, oldPosition, -reorderLength, t) |
diff --git a/server/helpers/custom-validators/misc.ts b/server/helpers/custom-validators/misc.ts index 17750379d..3dc5504e3 100644 --- a/server/helpers/custom-validators/misc.ts +++ b/server/helpers/custom-validators/misc.ts | |||
@@ -86,7 +86,7 @@ function isFileValid (options: { | |||
86 | 86 | ||
87 | // The file exists | 87 | // The file exists |
88 | const file = fileArray[0] | 88 | const file = fileArray[0] |
89 | if (!file || !file.originalname) return false | 89 | if (!file?.originalname) return false |
90 | 90 | ||
91 | // Check size | 91 | // Check size |
92 | if ((maxSize !== null) && file.size > maxSize) return false | 92 | if ((maxSize !== null) && file.size > maxSize) return false |
diff --git a/server/helpers/ffmpeg/ffmpeg-commons.ts b/server/helpers/ffmpeg/ffmpeg-commons.ts index b01989899..3906a2089 100644 --- a/server/helpers/ffmpeg/ffmpeg-commons.ts +++ b/server/helpers/ffmpeg/ffmpeg-commons.ts | |||
@@ -38,7 +38,7 @@ function getFFmpegVersion () { | |||
38 | return execPromise(`${ffmpegPath} -version`) | 38 | return execPromise(`${ffmpegPath} -version`) |
39 | .then(stdout => { | 39 | .then(stdout => { |
40 | const parsed = stdout.match(/ffmpeg version .?(\d+\.\d+(\.\d+)?)/) | 40 | const parsed = stdout.match(/ffmpeg version .?(\d+\.\d+(\.\d+)?)/) |
41 | if (!parsed || !parsed[1]) return rej(new Error(`Could not find ffmpeg version in ${stdout}`)) | 41 | if (!parsed?.[1]) return rej(new Error(`Could not find ffmpeg version in ${stdout}`)) |
42 | 42 | ||
43 | // Fix ffmpeg version that does not include patch version (4.4 for example) | 43 | // Fix ffmpeg version that does not include patch version (4.4 for example) |
44 | let version = parsed[1] | 44 | let version = parsed[1] |
diff --git a/server/helpers/youtube-dl/youtube-dl-wrapper.ts b/server/helpers/youtube-dl/youtube-dl-wrapper.ts index 966b8df78..ac3cd190e 100644 --- a/server/helpers/youtube-dl/youtube-dl-wrapper.ts +++ b/server/helpers/youtube-dl/youtube-dl-wrapper.ts | |||
@@ -77,7 +77,7 @@ class YoutubeDLWrapper { | |||
77 | 77 | ||
78 | const subtitles = files.reduce((acc, filename) => { | 78 | const subtitles = files.reduce((acc, filename) => { |
79 | const matched = filename.match(/\.([a-z]{2})(-[a-z]+)?\.(vtt|ttml)/i) | 79 | const matched = filename.match(/\.([a-z]{2})(-[a-z]+)?\.(vtt|ttml)/i) |
80 | if (!matched || !matched[1]) return acc | 80 | if (!matched?.[1]) return acc |
81 | 81 | ||
82 | return [ | 82 | return [ |
83 | ...acc, | 83 | ...acc, |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 66eb31230..65940f4ae 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -711,7 +711,7 @@ const PREVIEWS_SIZE = { | |||
711 | height: 480, | 711 | height: 480, |
712 | minWidth: 400 | 712 | minWidth: 400 |
713 | } | 713 | } |
714 | const ACTOR_IMAGES_SIZE: { [key in ActorImageType]: { width: number, height: number }[]} = { | 714 | const ACTOR_IMAGES_SIZE: { [key in ActorImageType]: { width: number, height: number }[] } = { |
715 | [ActorImageType.AVATAR]: [ | 715 | [ActorImageType.AVATAR]: [ |
716 | { | 716 | { |
717 | width: 120, | 717 | width: 120, |
diff --git a/server/lib/activitypub/share.ts b/server/lib/activitypub/share.ts index 0fefcbbc5..af0dd510a 100644 --- a/server/lib/activitypub/share.ts +++ b/server/lib/activitypub/share.ts | |||
@@ -57,7 +57,7 @@ export { | |||
57 | 57 | ||
58 | async function addVideoShare (shareUrl: string, video: MVideoId) { | 58 | async function addVideoShare (shareUrl: string, video: MVideoId) { |
59 | const { body } = await doJSONRequest<any>(shareUrl, { activityPub: true }) | 59 | const { body } = await doJSONRequest<any>(shareUrl, { activityPub: true }) |
60 | if (!body || !body.actor) throw new Error('Body or body actor is invalid') | 60 | if (!body?.actor) throw new Error('Body or body actor is invalid') |
61 | 61 | ||
62 | const actorUrl = getAPId(body.actor) | 62 | const actorUrl = getAPId(body.actor) |
63 | if (checkUrlsSameHost(shareUrl, actorUrl) !== true) { | 63 | if (checkUrlsSameHost(shareUrl, actorUrl) !== true) { |
diff --git a/server/lib/job-queue/handlers/activitypub-cleaner.ts b/server/lib/job-queue/handlers/activitypub-cleaner.ts index 84c0a2de2..a25f00b0a 100644 --- a/server/lib/job-queue/handlers/activitypub-cleaner.ts +++ b/server/lib/job-queue/handlers/activitypub-cleaner.ts | |||
@@ -88,7 +88,7 @@ async function updateObjectIfNeeded <T> (options: { | |||
88 | const { body } = await doJSONRequest<any>(url, { activityPub: true }) | 88 | const { body } = await doJSONRequest<any>(url, { activityPub: true }) |
89 | 89 | ||
90 | // If not same id, check same host and update | 90 | // If not same id, check same host and update |
91 | if (!body || !body.id || !bodyValidator(body)) throw new Error(`Body or body id of ${url} is invalid`) | 91 | if (!body?.id || !bodyValidator(body)) throw new Error(`Body or body id of ${url} is invalid`) |
92 | 92 | ||
93 | if (body.type === 'Tombstone') { | 93 | if (body.type === 'Tombstone') { |
94 | return on404OrTombstone() | 94 | return on404OrTombstone() |
diff --git a/server/lib/job-queue/handlers/video-import.ts b/server/lib/job-queue/handlers/video-import.ts index 83d582cb4..4d361c7b9 100644 --- a/server/lib/job-queue/handlers/video-import.ts +++ b/server/lib/job-queue/handlers/video-import.ts | |||
@@ -107,7 +107,7 @@ async function processYoutubeDLImport (job: Job, videoImport: MVideoImportDefaul | |||
107 | 107 | ||
108 | async function getVideoImportOrDie (payload: VideoImportPayload) { | 108 | async function getVideoImportOrDie (payload: VideoImportPayload) { |
109 | const videoImport = await VideoImportModel.loadAndPopulateVideo(payload.videoImportId) | 109 | const videoImport = await VideoImportModel.loadAndPopulateVideo(payload.videoImportId) |
110 | if (!videoImport || !videoImport.Video) { | 110 | if (!videoImport?.Video) { |
111 | throw new Error(`Cannot import video ${payload.videoImportId}: the video import or video linked to this import does not exist anymore.`) | 111 | throw new Error(`Cannot import video ${payload.videoImportId}: the video import or video linked to this import does not exist anymore.`) |
112 | } | 112 | } |
113 | 113 | ||
diff --git a/server/lib/moderation.ts b/server/lib/moderation.ts index 3cc92ca30..dc5d8c83c 100644 --- a/server/lib/moderation.ts +++ b/server/lib/moderation.ts | |||
@@ -220,7 +220,7 @@ async function createAbuse (options: { | |||
220 | base: FilteredModelAttributes<AbuseModel> | 220 | base: FilteredModelAttributes<AbuseModel> |
221 | reporterAccount: MAccountDefault | 221 | reporterAccount: MAccountDefault |
222 | flaggedAccount: MAccountLight | 222 | flaggedAccount: MAccountLight |
223 | associateFun: (abuseInstance: MAbuseFull) => Promise<{ isOwned: boolean} > | 223 | associateFun: (abuseInstance: MAbuseFull) => Promise<{ isOwned: boolean }> |
224 | skipNotification: boolean | 224 | skipNotification: boolean |
225 | transaction: Transaction | 225 | transaction: Transaction |
226 | }) { | 226 | }) { |
diff --git a/server/lib/schedulers/plugins-check-scheduler.ts b/server/lib/schedulers/plugins-check-scheduler.ts index 06450fa01..820c01693 100644 --- a/server/lib/schedulers/plugins-check-scheduler.ts +++ b/server/lib/schedulers/plugins-check-scheduler.ts | |||
@@ -33,7 +33,7 @@ export class PluginsCheckScheduler extends AbstractScheduler { | |||
33 | const chunks = chunk(plugins, 10) | 33 | const chunks = chunk(plugins, 10) |
34 | for (const chunk of chunks) { | 34 | for (const chunk of chunks) { |
35 | // Find plugins according to their npm name | 35 | // Find plugins according to their npm name |
36 | const pluginIndex: { [npmName: string]: PluginModel} = {} | 36 | const pluginIndex: { [npmName: string]: PluginModel } = {} |
37 | for (const plugin of chunk) { | 37 | for (const plugin of chunk) { |
38 | pluginIndex[PluginModel.buildNpmName(plugin.name, plugin.type)] = plugin | 38 | pluginIndex[PluginModel.buildNpmName(plugin.name, plugin.type)] = plugin |
39 | } | 39 | } |
diff --git a/server/middlewares/activitypub.ts b/server/middlewares/activitypub.ts index 0064a4760..261b9f690 100644 --- a/server/middlewares/activitypub.ts +++ b/server/middlewares/activitypub.ts | |||
@@ -125,7 +125,7 @@ async function checkJsonLDSignature (req: Request, res: Response) { | |||
125 | return wrapWithSpanAndContext('peertube.activitypub.JSONLDSignature', async () => { | 125 | return wrapWithSpanAndContext('peertube.activitypub.JSONLDSignature', async () => { |
126 | const signatureObject: ActivityPubSignature = req.body.signature | 126 | const signatureObject: ActivityPubSignature = req.body.signature |
127 | 127 | ||
128 | if (!signatureObject || !signatureObject.creator) { | 128 | if (!signatureObject?.creator) { |
129 | res.fail({ | 129 | res.fail({ |
130 | status: HttpStatusCode.FORBIDDEN_403, | 130 | status: HttpStatusCode.FORBIDDEN_403, |
131 | message: 'Object and creator signature do not match' | 131 | message: 'Object and creator signature do not match' |
diff --git a/server/middlewares/validators/user-subscriptions.ts b/server/middlewares/validators/user-subscriptions.ts index d01043c17..d8d3fc28b 100644 --- a/server/middlewares/validators/user-subscriptions.ts +++ b/server/middlewares/validators/user-subscriptions.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { arrayify } from '@shared/core-utils' | ||
2 | import express from 'express' | 1 | import express from 'express' |
3 | import { body, param, query } from 'express-validator' | 2 | import { body, param, query } from 'express-validator' |
3 | import { arrayify } from '@shared/core-utils' | ||
4 | import { HttpStatusCode } from '../../../shared/models/http/http-error-codes' | 4 | import { HttpStatusCode } from '../../../shared/models/http/http-error-codes' |
5 | import { areValidActorHandles, isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor' | 5 | import { areValidActorHandles, isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor' |
6 | import { WEBSERVER } from '../../initializers/constants' | 6 | import { WEBSERVER } from '../../initializers/constants' |
@@ -60,7 +60,7 @@ const userSubscriptionGetValidator = [ | |||
60 | state: 'accepted' | 60 | state: 'accepted' |
61 | }) | 61 | }) |
62 | 62 | ||
63 | if (!subscription || !subscription.ActorFollowing.VideoChannel) { | 63 | if (!subscription?.ActorFollowing.VideoChannel) { |
64 | return res.fail({ | 64 | return res.fail({ |
65 | status: HttpStatusCode.NOT_FOUND_404, | 65 | status: HttpStatusCode.NOT_FOUND_404, |
66 | message: `Subscription ${req.params.uri} not found.` | 66 | message: `Subscription ${req.params.uri} not found.` |
diff --git a/server/models/abuse/abuse.ts b/server/models/abuse/abuse.ts index f85f48e86..4c6a96a86 100644 --- a/server/models/abuse/abuse.ts +++ b/server/models/abuse/abuse.ts | |||
@@ -436,7 +436,7 @@ export class AbuseModel extends Model<Partial<AttributesOnly<AbuseModel>>> { | |||
436 | 436 | ||
437 | buildBaseVideoCommentAbuse (this: MAbuseUserFormattable) { | 437 | buildBaseVideoCommentAbuse (this: MAbuseUserFormattable) { |
438 | // Associated video comment could have been destroyed if the video has been deleted | 438 | // Associated video comment could have been destroyed if the video has been deleted |
439 | if (!this.VideoCommentAbuse || !this.VideoCommentAbuse.VideoComment) return null | 439 | if (!this.VideoCommentAbuse?.VideoComment) return null |
440 | 440 | ||
441 | const entity = this.VideoCommentAbuse.VideoComment | 441 | const entity = this.VideoCommentAbuse.VideoComment |
442 | 442 | ||
diff --git a/server/models/server/plugin.ts b/server/models/server/plugin.ts index 6a5d80182..71c205ffa 100644 --- a/server/models/server/plugin.ts +++ b/server/models/server/plugin.ts | |||
@@ -122,7 +122,7 @@ export class PluginModel extends Model<Partial<AttributesOnly<PluginModel>>> { | |||
122 | 122 | ||
123 | return PluginModel.findOne(query) | 123 | return PluginModel.findOne(query) |
124 | .then(p => { | 124 | .then(p => { |
125 | if (!p || !p.settings || p.settings === undefined) { | 125 | if (!p?.settings || p.settings === undefined) { |
126 | const registered = registeredSettings.find(s => s.name === settingName) | 126 | const registered = registeredSettings.find(s => s.name === settingName) |
127 | if (!registered || registered.default === undefined) return undefined | 127 | if (!registered || registered.default === undefined) return undefined |
128 | 128 | ||
@@ -152,7 +152,7 @@ export class PluginModel extends Model<Partial<AttributesOnly<PluginModel>>> { | |||
152 | const result: SettingEntries = {} | 152 | const result: SettingEntries = {} |
153 | 153 | ||
154 | for (const name of settingNames) { | 154 | for (const name of settingNames) { |
155 | if (!p || !p.settings || p.settings[name] === undefined) { | 155 | if (!p?.settings || p.settings[name] === undefined) { |
156 | const registered = registeredSettings.find(s => s.name === name) | 156 | const registered = registeredSettings.find(s => s.name === name) |
157 | 157 | ||
158 | if (registered?.default !== undefined) { | 158 | if (registered?.default !== undefined) { |
diff --git a/server/models/video/formatter/video-format-utils.ts b/server/models/video/formatter/video-format-utils.ts index 240619f69..f285db477 100644 --- a/server/models/video/formatter/video-format-utils.ts +++ b/server/models/video/formatter/video-format-utils.ts | |||
@@ -58,7 +58,7 @@ export type VideoFormattingJSONOptions = { | |||
58 | } | 58 | } |
59 | 59 | ||
60 | function guessAdditionalAttributesFromQuery (query: VideosCommonQueryAfterSanitize): VideoFormattingJSONOptions { | 60 | function guessAdditionalAttributesFromQuery (query: VideosCommonQueryAfterSanitize): VideoFormattingJSONOptions { |
61 | if (!query || !query.include) return {} | 61 | if (!query?.include) return {} |
62 | 62 | ||
63 | return { | 63 | return { |
64 | additionalAttributes: { | 64 | additionalAttributes: { |
diff --git a/server/models/video/sql/video/shared/abstract-video-query-builder.ts b/server/models/video/sql/video/shared/abstract-video-query-builder.ts index 3c74b0ea6..f0ce69501 100644 --- a/server/models/video/sql/video/shared/abstract-video-query-builder.ts +++ b/server/models/video/sql/video/shared/abstract-video-query-builder.ts | |||
@@ -302,7 +302,7 @@ export class AbstractVideoQueryBuilder extends AbstractRunQuery { | |||
302 | } | 302 | } |
303 | 303 | ||
304 | protected buildAttributesObject (prefixKey: string, attributeKeys: string[]) { | 304 | protected buildAttributesObject (prefixKey: string, attributeKeys: string[]) { |
305 | const result: { [id: string]: string} = {} | 305 | const result: { [id: string]: string } = {} |
306 | 306 | ||
307 | const prefixValue = prefixKey.replace(/->/g, '.') | 307 | const prefixValue = prefixKey.replace(/->/g, '.') |
308 | 308 | ||
diff --git a/server/tests/api/live/live-fast-restream.ts b/server/tests/api/live/live-fast-restream.ts index 971df1a61..c0bb8d529 100644 --- a/server/tests/api/live/live-fast-restream.ts +++ b/server/tests/api/live/live-fast-restream.ts | |||
@@ -130,7 +130,7 @@ describe('Fast restream in live', function () { | |||
130 | }) | 130 | }) |
131 | 131 | ||
132 | it('Should correctly fast reastream in a permanent live with and without save replay', async function () { | 132 | it('Should correctly fast reastream in a permanent live with and without save replay', async function () { |
133 | this.timeout(240000) | 133 | this.timeout(480000) |
134 | 134 | ||
135 | // A test can take a long time, so prefer to run them in parallel | 135 | // A test can take a long time, so prefer to run them in parallel |
136 | await Promise.all([ | 136 | await Promise.all([ |
diff --git a/shared/core-utils/i18n/i18n.ts b/shared/core-utils/i18n/i18n.ts index abc7acc8b..b720fb84e 100644 --- a/shared/core-utils/i18n/i18n.ts +++ b/shared/core-utils/i18n/i18n.ts | |||
@@ -82,7 +82,7 @@ export function isDefaultLocale (locale: string) { | |||
82 | } | 82 | } |
83 | 83 | ||
84 | export function peertubeTranslate (str: string, translations?: { [ id: string ]: string }) { | 84 | export function peertubeTranslate (str: string, translations?: { [ id: string ]: string }) { |
85 | if (!translations || !translations[str]) return str | 85 | if (!translations?.[str]) return str |
86 | 86 | ||
87 | return translations[str] | 87 | return translations[str] |
88 | } | 88 | } |
diff --git a/shared/server-commands/server/server.ts b/shared/server-commands/server/server.ts index c062e6986..f2ca51431 100644 --- a/shared/server-commands/server/server.ts +++ b/shared/server-commands/server/server.ts | |||
@@ -259,7 +259,7 @@ export class PeerTubeServer { | |||
259 | 259 | ||
260 | const onPeerTubeExit = () => rej(new Error('Process exited:\n' + aggregatedLogs)) | 260 | const onPeerTubeExit = () => rej(new Error('Process exited:\n' + aggregatedLogs)) |
261 | const onParentExit = () => { | 261 | const onParentExit = () => { |
262 | if (!this.app || !this.app.pid) return | 262 | if (!this.app?.pid) return |
263 | 263 | ||
264 | try { | 264 | try { |
265 | process.kill(self.app.pid) | 265 | process.kill(self.app.pid) |