diff --git a/package-lock.json b/package-lock.json index a5d811d..f0f2e66 100755 --- a/package-lock.json +++ b/package-lock.json @@ -42,9 +42,11 @@ "devDependencies": { "@types/escape-html": "^1.0.1", "@types/express": "^4.17.13", + "@types/ffmpeg-static": "^3.0.0", "@types/fs-extra": "^9.0.12", "@types/node": "^16.9.0", "@types/node-fetch": "^2.5.12", + "@types/stream-to-array": "^2.3.0", "@types/ws": "^7.4.7" }, "engines": { @@ -777,6 +779,12 @@ "@types/range-parser": "*" } }, + "node_modules/@types/ffmpeg-static": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/ffmpeg-static/-/ffmpeg-static-3.0.0.tgz", + "integrity": "sha512-JTwV8fFQYUgp8VLUKLd8zHfhFOoTTszMlofnWINAZYWSd/iR2ZZHJsWanUhBG4+c8QPfWE8P7t3nAjSxTNjevQ==", + "dev": true + }, "node_modules/@types/fs-extra": { "version": "9.0.12", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.12.tgz", @@ -830,6 +838,15 @@ "@types/node": "*" } }, + "node_modules/@types/stream-to-array": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@types/stream-to-array/-/stream-to-array-2.3.0.tgz", + "integrity": "sha512-s8Y6/EV1LPn9fDlJKSlD8r+14hWXVDn+wPAGwWRzTUq/4MqdoQNEzQxP6Jq91qvFYxR3OlFAPXcv6ToplnAgFQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/ws": { "version": "7.4.7", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", @@ -5261,6 +5278,12 @@ "@types/range-parser": "*" } }, + "@types/ffmpeg-static": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/ffmpeg-static/-/ffmpeg-static-3.0.0.tgz", + "integrity": "sha512-JTwV8fFQYUgp8VLUKLd8zHfhFOoTTszMlofnWINAZYWSd/iR2ZZHJsWanUhBG4+c8QPfWE8P7t3nAjSxTNjevQ==", + "dev": true + }, "@types/fs-extra": { "version": "9.0.12", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.12.tgz", @@ -5314,6 +5337,15 @@ "@types/node": "*" } }, + "@types/stream-to-array": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@types/stream-to-array/-/stream-to-array-2.3.0.tgz", + "integrity": "sha512-s8Y6/EV1LPn9fDlJKSlD8r+14hWXVDn+wPAGwWRzTUq/4MqdoQNEzQxP6Jq91qvFYxR3OlFAPXcv6ToplnAgFQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/ws": { "version": "7.4.7", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", diff --git a/package.json b/package.json index eea8085..c9e53e1 100755 --- a/package.json +++ b/package.json @@ -69,9 +69,11 @@ "devDependencies": { "@types/escape-html": "^1.0.1", "@types/express": "^4.17.13", + "@types/ffmpeg-static": "^3.0.0", "@types/fs-extra": "^9.0.12", "@types/node": "^16.9.0", "@types/node-fetch": "^2.5.12", + "@types/stream-to-array": "^2.3.0", "@types/ws": "^7.4.7" } } diff --git a/src/auth.js b/src/auth.ts similarity index 73% rename from src/auth.js rename to src/auth.ts index 1b1269a..dd3d813 100644 --- a/src/auth.js +++ b/src/auth.ts @@ -2,16 +2,17 @@ * Used for global auth management */ -const fs = require('fs-extra'); -const { log, path, arrayEquals } = require('./utils'); +import fs from 'fs-extra'; +import { log, path, arrayEquals } from './utils'; const users = require('../auth.json').users || {}; // Monitor auth.json for changes (triggered by running 'npm run new-token') fs.watch(path('auth.json'), { persistent: false }, - (eventType) => eventType === 'change' && fs.readJson(path('auth.json')) - .then((json) => { + (eventType: String) => eventType === 'change' && fs.readJson(path('auth.json')) + .then((json: { users: JSON[] }) => { if (!(arrayEquals(Object.keys(users), Object.keys(json.users)))) { + // @ts-ignore Object.keys(json.users).forEach((token) => (!Object.prototype.hasOwnProperty.call(users, token)) && (users[token] = json.users[token])); log.info('New token added', Object.keys(users)[Object.keys(users).length - 1] || 'No new token'); } diff --git a/src/data.js b/src/data.ts similarity index 100% rename from src/data.js rename to src/data.ts diff --git a/src/hash.js b/src/hash.js deleted file mode 100644 index 3610048..0000000 --- a/src/hash.js +++ /dev/null @@ -1,17 +0,0 @@ -const fs = require('fs-extra'); -const crypto = require('crypto'); -const toArray = require('stream-to-array'); -const { log } = require('./utils'); - -/** - * Generates a SHA1 hash for the provided file - * @param {*} file The file to hash - * @returns The SHA1 hash - */ -module.exports = (file) => - new Promise((resolve, reject) => - toArray((fs.createReadStream(file.path))) - .then((parts) => Buffer.concat(parts.map((part) => (Buffer.isBuffer(part) ? part : Buffer.from(part))))) - .then((buf) => crypto.createHash('sha1').update(buf).digest('hex')) // skipcq: JS-D003 - .then((hash) => log.debug(`Hash for ${file.originalname}`, hash, 'SHA1, hex').callback(resolve, hash)) - .catch(reject)); diff --git a/src/hash.ts b/src/hash.ts new file mode 100644 index 0000000..998bd63 --- /dev/null +++ b/src/hash.ts @@ -0,0 +1,18 @@ +import { FileData } from './definitions'; +import fs from 'fs-extra'; +import crypto from 'crypto'; +import toArray from 'stream-to-array'; +import { log } from './utils'; + +/** + * Generates a SHA1 hash for the provided file + * @param {*} file The file to hash + * @returns The SHA1 hash + */ +module.exports = (file: FileData) => + new Promise((resolve, reject) => + toArray((fs.createReadStream(file.path))) + .then((parts: any[]) => Buffer.concat(parts.map((part: any) => (Buffer.isBuffer(part) ? part : Buffer.from(part))))) + .then((buf: Buffer) => crypto.createHash('sha1').update(buf).digest('hex')) // skipcq: JS-D003 + .then((hash: String) => log.debug(`Hash for ${file.originalname}`, hash, 'SHA1, hex').callback(resolve, hash)) + .catch(reject)); diff --git a/src/thumbnails.js b/src/thumbnails.ts similarity index 80% rename from src/thumbnails.js rename to src/thumbnails.ts index 22bce7f..0253a78 100644 --- a/src/thumbnails.js +++ b/src/thumbnails.ts @@ -1,8 +1,9 @@ -const ffmpeg = require('ffmpeg-static'); -const Jimp = require('jimp'); +import { FileData } from "./definitions"; +import ffmpeg from 'ffmpeg-static'; +import Jimp from 'jimp'; const shell = require('any-shell-escape'); -const { exec } = require('child_process'); -const { isProd, path } = require('./utils'); +import { exec } from 'child_process'; +import { isProd, path } from './utils'; const { diskFilePath } = require('../config.json'); // Thumbnail parameters @@ -18,7 +19,7 @@ const THUMBNAIL = { * @param {String} dest Path of the output file * @returns {String} The command to execute */ -function getCommand(src, dest) { +function getCommand(src: String, dest: String) { return shell([ ffmpeg, '-y', '-v', (isProd ? 'error' : 'debug'), // Log level @@ -35,7 +36,7 @@ function getCommand(src, dest) { * @param {String} oldName The original filename * @returns {String} The filename for the thumbnail */ -function getNewName(oldName) { +function getNewName(oldName: String) { return oldName.concat('.thumbnail.jpg'); } @@ -44,7 +45,7 @@ function getNewName(oldName) { * @param {String} oldName The original filename * @returns {String} The path to the thumbnail */ -function getNewNamePath(oldName) { +function getNewNamePath(oldName: String) { return path(diskFilePath, 'thumbnails/', getNewName(oldName)); } @@ -52,10 +53,11 @@ function getNewNamePath(oldName) { * Extracts an image from a video file to use as a thumbnail, using ffmpeg * @param {*} file The video file to pull a frame from */ -function getVideoThumbnail(file) { - return new Promise((resolve, reject) => exec( +function getVideoThumbnail(file: FileData) { + return new Promise((resolve: Function, reject: Function) => exec( getCommand(file.path, getNewNamePath(file.randomId)), - (err) => (err ? reject(err) : resolve()) + // @ts-ignore + (err: Error) => (err ? reject(err) : resolve()) )); } @@ -63,7 +65,7 @@ function getVideoThumbnail(file) { * Generates a thumbnail for the provided image * @param {*} file The file to generate a thumbnail for */ -function getImageThumbnail(file) { +function getImageThumbnail(file: FileData) { return new Promise((resolve, reject) => Jimp.read(file.path) .then((image) => image @@ -79,7 +81,7 @@ function getImageThumbnail(file) { * @param {*} file The file to generate a thumbnail for * @returns The thumbnail filename (NOT the path) */ -module.exports = (file) => +module.exports = (file: FileData) => new Promise((resolve, reject) => (file.is.video ? getVideoThumbnail : file.is.image ? getImageThumbnail : () => Promise.resolve())(file) .then(() => resolve((file.is.video || file.is.image) ? getNewName(file.randomId) : file.is.audio ? 'views/ass-audio-icon.png' : 'views/ass-file-icon.png')) diff --git a/src/vibrant.js b/src/vibrant.ts similarity index 59% rename from src/vibrant.js rename to src/vibrant.ts index 6079786..38f539d 100644 --- a/src/vibrant.js +++ b/src/vibrant.ts @@ -1,5 +1,6 @@ -const Vibrant = require('node-vibrant'); -const { randomHexColour } = require('./utils'); +import { FileData } from './definitions'; +import Vibrant from 'node-vibrant'; +import { randomHexColour } from './utils'; // Vibrant parameters const COLOR_COUNT = 256; @@ -11,13 +12,13 @@ const QUALITY = 3; * @param {*} resolve Runs if Promise was successful * @param {*} reject Runs if Promise failed */ -function getVibrant(file, resolve, reject) { +function getVibrant(file: FileData, resolve: Function, reject: Function) { Vibrant.from(file.path) .maxColorCount(COLOR_COUNT) .quality(QUALITY) .getPalette() - .then((palettes) => resolve(palettes[Object.keys(palettes).sort((a, b) => palettes[b].population - palettes[a].population)[0]].hex)) - .catch(reject); + .then((palettes) => resolve(palettes[Object.keys(palettes).sort((a, b) => palettes[b]!.population - palettes[a]!.population)[0]]!.hex)) + .catch(() => reject); } /** @@ -25,4 +26,4 @@ function getVibrant(file, resolve, reject) { * @param {*} file The file to get a colour from * @returns The Vibrant colour as a Hex value (or random Hex value for videos) */ -module.exports = (file) => new Promise((resolve, reject) => !file.is.image ? resolve(randomHexColour()) : getVibrant(file, resolve, reject)); // skipcq: JS-0229 +module.exports = (file: FileData) => new Promise((resolve, reject) => !file.is.image ? resolve(randomHexColour()) : getVibrant(file, resolve, reject)); // skipcq: JS-0229