Converted more files to typescript.

This commit is contained in:
SamTV12345 2024-01-21 12:53:52 +01:00
parent 93dffc0e37
commit c24ae14cf4
14 changed files with 94 additions and 51 deletions

View file

@ -47,13 +47,13 @@ exports.init = async () => {
}
for (const fn of ['get', 'set', 'findKeys', 'getSub', 'setSub', 'remove']) {
const f = exports.db[fn];
exports[fn] = async (...args) => await f.call(exports.db, ...args);
exports[fn] = async (...args:string[]) => await f.call(exports.db, ...args);
Object.setPrototypeOf(exports[fn], Object.getPrototypeOf(f));
Object.defineProperties(exports[fn], Object.getOwnPropertyDescriptors(f));
}
};
exports.shutdown = async (hookName, context) => {
exports.shutdown = async (hookName: string, context:any) => {
if (exports.db != null) await exports.db.close();
exports.db = null;
logger.log('Database closed');

View file

@ -34,9 +34,10 @@ class SessionStore extends Store {
for (const {timeout} of this._expirations.values()) clearTimeout(timeout);
}
async _updateExpirations(sid, sess, updateDbExp = true) {
async _updateExpirations(sid: string, sess: any, updateDbExp = true) {
const exp = this._expirations.get(sid) || {};
clearTimeout(exp.timeout);
// @ts-ignore
const {cookie: {expires} = {}} = sess || {};
if (expires) {
const sessExp = new Date(expires).getTime();
@ -63,23 +64,23 @@ class SessionStore extends Store {
return sess;
}
async _write(sid, sess) {
async _write(sid: string, sess: any) {
await DB.set(`sessionstorage:${sid}`, sess);
}
async _get(sid) {
async _get(sid: string) {
logger.debug(`GET ${sid}`);
const s = await DB.get(`sessionstorage:${sid}`);
return await this._updateExpirations(sid, s);
}
async _set(sid, sess) {
async _set(sid: string, sess:any) {
logger.debug(`SET ${sid}`);
sess = await this._updateExpirations(sid, sess);
if (sess != null) await this._write(sid, sess);
}
async _destroy(sid) {
async _destroy(sid:string) {
logger.debug(`DESTROY ${sid}`);
clearTimeout((this._expirations.get(sid) || {}).timeout);
this._expirations.delete(sid);
@ -89,7 +90,7 @@ class SessionStore extends Store {
// Note: express-session might call touch() before it calls set() for the first time. Ideally this
// would behave like set() in that case but it's OK if it doesn't -- express-session will call
// set() soon enough.
async _touch(sid, sess) {
async _touch(sid: string, sess:any) {
logger.debug(`TOUCH ${sid}`);
sess = await this._updateExpirations(sid, sess, false);
if (sess == null) return; // Already expired.

View file

@ -0,0 +1,5 @@
export type AsyncQueueTask = {
srcFile: string,
destFile: string,
type: string
}

View file

@ -0,0 +1,8 @@
import {Readable} from "node:stream";
import {ChildProcess} from "node:child_process";
export type PromiseWithStd = {
stdout?: Readable|null,
stderr?: Readable|null,
child?: ChildProcess
} & Promise<any>

View file

@ -0,0 +1,15 @@
export type RunCMDOptions = {
cwd?: string,
stdio?: string[],
env?: NodeJS.ProcessEnv
}
export type RunCMDPromise = {
stdout?:Function,
stderr?:Function
}
export type ErrorExtended = {
code?: number|null,
signal?: NodeJS.Signals|null
}

View file

@ -2,7 +2,7 @@
const securityManager = require('./db/SecurityManager');
// checks for padAccess
module.exports = async (req, res) => {
module.exports = async (req: { params?: any; cookies?: any; session?: any; }, res: { status: (arg0: number) => { (): any; new(): any; send: { (arg0: string): void; new(): any; }; }; }) => {
const {session: {user} = {}} = req;
const accessObj = await securityManager.checkAccess(
req.params.pad, req.cookies.sessionID, req.cookies.token, user);

View file

@ -4,6 +4,6 @@ const measured = require('measured-core');
module.exports = measured.createCollection();
module.exports.shutdown = async (hookName, context) => {
module.exports.shutdown = async (hookName: string, context:any) => {
module.exports.end();
};

View file

@ -19,6 +19,9 @@
* limitations under the License.
*/
import {ChildProcess} from "node:child_process";
import {AsyncQueueTask} from "../models/AsyncQueueTask";
const spawn = require('child_process').spawn;
const async = require('async');
const settings = require('./Settings');
@ -27,13 +30,13 @@ const os = require('os');
// on windows we have to spawn a process for each convertion,
// cause the plugin abicommand doesn't exist on this platform
if (os.type().indexOf('Windows') > -1) {
exports.convertFile = async (srcFile, destFile, type) => {
exports.convertFile = async (srcFile: string, destFile: string, type: string) => {
const abiword = spawn(settings.abiword, [`--to=${destFile}`, srcFile]);
let stdoutBuffer = '';
abiword.stdout.on('data', (data) => { stdoutBuffer += data.toString(); });
abiword.stderr.on('data', (data) => { stdoutBuffer += data.toString(); });
await new Promise((resolve, reject) => {
abiword.on('exit', (code) => {
abiword.stdout.on('data', (data: string) => { stdoutBuffer += data.toString(); });
abiword.stderr.on('data', (data: string) => { stdoutBuffer += data.toString(); });
await new Promise<void>((resolve, reject) => {
abiword.on('exit', (code: number) => {
if (code !== 0) return reject(new Error(`Abiword died with exit code ${code}`));
if (stdoutBuffer !== '') {
console.log(stdoutBuffer);
@ -46,13 +49,13 @@ if (os.type().indexOf('Windows') > -1) {
// communicate with it via stdin/stdout
// thats much faster, about factor 10
} else {
let abiword;
let stdoutCallback = null;
let abiword: ChildProcess;
let stdoutCallback: Function|null = null;
const spawnAbiword = () => {
abiword = spawn(settings.abiword, ['--plugin', 'AbiCommand']);
let stdoutBuffer = '';
let firstPrompt = true;
abiword.stderr.on('data', (data) => { stdoutBuffer += data.toString(); });
abiword.stderr!.on('data', (data) => { stdoutBuffer += data.toString(); });
abiword.on('exit', (code) => {
spawnAbiword();
if (stdoutCallback != null) {
@ -60,7 +63,7 @@ if (os.type().indexOf('Windows') > -1) {
stdoutCallback = null;
}
});
abiword.stdout.on('data', (data) => {
abiword.stdout!.on('data', (data) => {
stdoutBuffer += data.toString();
// we're searching for the prompt, cause this means everything we need is in the buffer
if (stdoutBuffer.search('AbiWord:>') !== -1) {
@ -76,15 +79,15 @@ if (os.type().indexOf('Windows') > -1) {
};
spawnAbiword();
const queue = async.queue((task, callback) => {
abiword.stdin.write(`convert ${task.srcFile} ${task.destFile} ${task.type}\n`);
stdoutCallback = (err) => {
const queue = async.queue((task: AsyncQueueTask, callback:Function) => {
abiword.stdin!.write(`convert ${task.srcFile} ${task.destFile} ${task.type}\n`);
stdoutCallback = (err: string) => {
if (err != null) console.error('Abiword File failed to convert', err);
callback(err);
};
}, 1);
exports.convertFile = async (srcFile, destFile, type) => {
exports.convertFile = async (srcFile: string, destFile: string, type: string) => {
await queue.pushAsync({srcFile, destFile, type});
};
}

View file

@ -18,7 +18,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const log4js = require('log4js');
const path = require('path');
const _ = require('underscore');
@ -29,7 +28,7 @@ const absPathLogger = log4js.getLogger('AbsolutePaths');
* findEtherpadRoot() computes its value only on first invocation.
* Subsequent invocations are served from this variable.
*/
let etherpadRoot = null;
let etherpadRoot: string|null = null;
/**
* If stringArray's last elements are exactly equal to lastDesiredElements,
@ -41,7 +40,7 @@ let etherpadRoot = null;
* @return {string[]|boolean} The shortened array, or false if there was no
* overlap.
*/
const popIfEndsWith = (stringArray, lastDesiredElements) => {
const popIfEndsWith = (stringArray: string[], lastDesiredElements: string[]): string[] | false => {
if (stringArray.length <= lastDesiredElements.length) {
absPathLogger.debug(`In order to pop "${lastDesiredElements.join(path.sep)}" ` +
`from "${stringArray.join(path.sep)}", it should contain at least ` +
@ -131,7 +130,7 @@ exports.findEtherpadRoot = () => {
* it is returned unchanged. Otherwise it is interpreted
* relative to exports.root.
*/
exports.makeAbsolute = (somePath) => {
exports.makeAbsolute = (somePath: string) => {
if (path.isAbsolute(somePath)) {
return somePath;
}
@ -150,10 +149,8 @@ exports.makeAbsolute = (somePath) => {
* a subdirectory of the base one
* @return {boolean}
*/
exports.isSubdir = (parent, arbitraryDir) => {
exports.isSubdir = (parent: string, arbitraryDir: string): boolean => {
// modified from: https://stackoverflow.com/questions/37521893/determine-if-a-path-is-subdirectory-of-another-in-node-js#45242825
const relative = path.relative(parent, arbitraryDir);
const isSubdir = !!relative && !relative.startsWith('..') && !path.isAbsolute(relative);
return isSubdir;
return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative);
};

View file

@ -3,8 +3,8 @@
* Generates a random String with the given length. Is needed to generate the
* Author, Group, readonly, session Ids
*/
const crypto = require('crypto');
const cryptoMod = require('crypto');
const randomString = (len) => crypto.randomBytes(len).toString('hex');
const randomString = (len: string) => cryptoMod.randomBytes(len).toString('hex');
module.exports = randomString;

View file

@ -1,5 +1,10 @@
'use strict';
import {ErrorExtended, RunCMDOptions, RunCMDPromise} from "../models/RunCMDOptions";
import {ChildProcess} from "node:child_process";
import {PromiseWithStd} from "../models/PromiseWithStd";
import {Readable} from "node:stream";
const spawn = require('cross-spawn');
const log4js = require('log4js');
const path = require('path');
@ -7,12 +12,12 @@ const settings = require('./Settings');
const logger = log4js.getLogger('runCmd');
const logLines = (readable, logLineFn) => {
readable.setEncoding('utf8');
const logLines = (readable: undefined | Readable | null, logLineFn: (arg0: (string | undefined)) => void) => {
readable!.setEncoding('utf8');
// The process won't necessarily write full lines every time -- it might write a part of a line
// then write the rest of the line later.
let leftovers = '';
readable.on('data', (chunk) => {
let leftovers: string| undefined = '';
readable!.on('data', (chunk) => {
const lines = chunk.split('\n');
if (lines.length === 0) return;
lines[0] = leftovers + lines[0];
@ -21,7 +26,7 @@ const logLines = (readable, logLineFn) => {
logLineFn(line);
}
});
readable.on('end', () => {
readable!.on('end', () => {
if (leftovers !== '') logLineFn(leftovers);
leftovers = '';
});
@ -69,7 +74,7 @@ const logLines = (readable, logLineFn) => {
* - `stderr`: Similar to `stdout` but for stderr.
* - `child`: The ChildProcess object.
*/
module.exports = exports = (args, opts = {}) => {
module.exports = exports = (args: string[], opts:RunCMDOptions = {}) => {
logger.debug(`Executing command: ${args.join(' ')}`);
opts = {cwd: settings.root, ...opts};
@ -82,8 +87,8 @@ module.exports = exports = (args, opts = {}) => {
: opts.stdio === 'string' ? [null, 'string', 'string']
: Array(3).fill(opts.stdio);
const cmdLogger = log4js.getLogger(`runCmd|${args[0]}`);
if (stdio[1] == null) stdio[1] = (line) => cmdLogger.info(line);
if (stdio[2] == null) stdio[2] = (line) => cmdLogger.error(line);
if (stdio[1] == null) stdio[1] = (line: string) => cmdLogger.info(line);
if (stdio[2] == null) stdio[2] = (line: string) => cmdLogger.error(line);
const stdioLoggers = [];
const stdioSaveString = [];
for (const fd of [1, 2]) {
@ -116,13 +121,13 @@ module.exports = exports = (args, opts = {}) => {
// Create an error object to use in case the process fails. This is done here rather than in the
// process's `exit` handler so that we get a useful stack trace.
const procFailedErr = new Error();
const procFailedErr: Error & ErrorExtended = new Error();
const proc = spawn(args[0], args.slice(1), opts);
const streams = [undefined, proc.stdout, proc.stderr];
const proc: ChildProcess = spawn(args[0], args.slice(1), opts);
const streams:[undefined, Readable|null, Readable|null] = [undefined, proc.stdout, proc.stderr];
let px;
const p = new Promise((resolve, reject) => { px = {resolve, reject}; });
let px: { reject: any; resolve: any; };
const p:PromiseWithStd = new Promise<string>((resolve, reject) => { px = {resolve, reject}; });
[, p.stdout, p.stderr] = streams;
p.child = proc;
@ -132,9 +137,10 @@ module.exports = exports = (args, opts = {}) => {
if (stdioLoggers[fd] != null) {
logLines(streams[fd], stdioLoggers[fd]);
} else if (stdioSaveString[fd]) {
// @ts-ignore
p[[null, 'stdout', 'stderr'][fd]] = stdioStringPromises[fd] = (async () => {
const chunks = [];
for await (const chunk of streams[fd]) chunks.push(chunk);
for await (const chunk of streams[fd]!) chunks.push(chunk);
return Buffer.concat(chunks).toString().replace(/\n+$/g, '');
})();
}

6
src/package-lock.json generated
View file

@ -409,6 +409,12 @@
"integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==",
"dev": true
},
"@types/async": {
"version": "3.2.24",
"resolved": "https://registry.npmjs.org/@types/async/-/async-3.2.24.tgz",
"integrity": "sha512-8iHVLHsCCOBKjCF2KwFe0p9Z3rfM9mL+sSP8btyR5vTjJRAqpBYD28/ZLgXPf0pjG1VxOvtCV/BgXkQbpSe8Hw==",
"dev": true
},
"@types/debug": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",

View file

@ -68,17 +68,18 @@
"terser": "^5.27.0",
"threads": "^1.7.0",
"tinycon": "0.6.8",
"tsx": "^4.7.0",
"ueberdb2": "^4.2.48",
"underscore": "1.13.6",
"unorm": "1.6.0",
"wtfnode": "^0.9.1",
"tsx": "^4.7.0"
"wtfnode": "^0.9.1"
},
"bin": {
"etherpad-healthcheck": "bin/etherpad-healthcheck",
"etherpad-lite": "node/server.ts"
},
"devDependencies": {
"@types/async": "^3.2.24",
"typescript": "^5.3.3",
"@types/node": "^20.11.5",
"eslint": "^8.56.0",

View file

@ -1,7 +1,8 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
"moduleDetection": "force",
"lib": ["es6"],
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
@ -11,7 +12,7 @@
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"target": "es6", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */