mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-09 01:13:55 +00:00
refactor: small type improvements (#759)
This commit is contained in:
@@ -27,7 +27,9 @@
|
||||
"ws": "^8.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/multer": "^1.4.11",
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/node-osc": "^6.0.2",
|
||||
"@types/websocket": "^1.0.5",
|
||||
|
||||
@@ -25,7 +25,7 @@ import { eventStore } from '../stores/EventStore.js';
|
||||
import { dispatchFromAdapter } from '../controllers/integrationController.js';
|
||||
import { logger } from '../classes/Logger.js';
|
||||
|
||||
let instance;
|
||||
let instance: SocketServer | null = null;
|
||||
|
||||
export class SocketServer implements IAdapter {
|
||||
private readonly MAX_PAYLOAD = 1024 * 256; // 256Kb
|
||||
@@ -50,7 +50,7 @@ export class SocketServer implements IAdapter {
|
||||
this.wss.on('connection', (ws) => {
|
||||
let clientId = getRandomName();
|
||||
this.clientIds.add(clientId);
|
||||
logger.info(LogOrigin.Client, `${this.wss.clients.size} Connections with new: ${clientId}`);
|
||||
logger.info(LogOrigin.Client, `${this.clientIds.size} Connections with new: ${clientId}`);
|
||||
|
||||
// send store payload on connect
|
||||
ws.send(
|
||||
@@ -70,8 +70,8 @@ export class SocketServer implements IAdapter {
|
||||
ws.on('error', console.error);
|
||||
|
||||
ws.on('close', () => {
|
||||
logger.info(LogOrigin.Client, `${this.wss.clients.size} Connections with disconnected: ${clientId}`);
|
||||
this.clientIds.delete(clientId);
|
||||
logger.info(LogOrigin.Client, `${this.clientIds.size} Connections with disconnected: ${clientId}`);
|
||||
});
|
||||
|
||||
ws.on('message', (data) => {
|
||||
|
||||
@@ -33,8 +33,8 @@ describe('objectFromPath()', () => {
|
||||
const obj = objectFromPath(arr);
|
||||
expect(obj).toStrictEqual(objExpected);
|
||||
});
|
||||
it('empty array creates undefinde object', () => {
|
||||
const arr = [];
|
||||
it('empty array creates undefined object', () => {
|
||||
const arr: string[] = [];
|
||||
const value = '1234567890';
|
||||
const objExpected = null;
|
||||
|
||||
|
||||
@@ -170,8 +170,8 @@ export const startServer = async () => {
|
||||
eventNext: state.eventNext,
|
||||
publicEventNext: state.publicEventNext,
|
||||
timer1: {
|
||||
duration: null,
|
||||
current: null,
|
||||
duration: 0,
|
||||
current: 0,
|
||||
playback: SimplePlayback.Stop,
|
||||
direction: SimpleDirection.CountDown,
|
||||
},
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
UserFields,
|
||||
Alias,
|
||||
Settings,
|
||||
HttpSettings,
|
||||
} from 'ontime-types';
|
||||
|
||||
import { data, db } from '../../modules/loadDb.js';
|
||||
@@ -98,7 +99,7 @@ export class DataProvider {
|
||||
await this.persist();
|
||||
}
|
||||
|
||||
static async setHttp(newData) {
|
||||
static async setHttp(newData: HttpSettings) {
|
||||
data.http = { ...newData };
|
||||
await this.persist();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@ export class SimpleTimer {
|
||||
|
||||
public start(timeNow: number): SimpleTimerState {
|
||||
if (this.state.playback === SimplePlayback.Pause) {
|
||||
const elapsedSincePause = this.pausedAt - this.startedAt;
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know these are not null in a timer that is paused
|
||||
const elapsedSincePause = this.pausedAt! - this.startedAt!;
|
||||
this.startedAt = timeNow - elapsedSincePause;
|
||||
} else if (this.state.playback === SimplePlayback.Stop) {
|
||||
this.startedAt = timeNow;
|
||||
|
||||
@@ -8,7 +8,7 @@ import type {
|
||||
ErrorResponse,
|
||||
ProjectFileListResponse,
|
||||
} from 'ontime-types';
|
||||
import { deepmerge } from 'ontime-utils';
|
||||
import { ExcelImportOptions, deepmerge } from 'ontime-utils';
|
||||
|
||||
import { RequestHandler, Request, Response } from 'express';
|
||||
import fs from 'fs';
|
||||
@@ -44,7 +44,7 @@ import { removeFileExtension } from '../utils/removeFileExtension.js';
|
||||
|
||||
// Create controller for GET request to '/ontime/poll'
|
||||
// Returns data for current state
|
||||
export const poll = async (_req, res) => {
|
||||
export const poll = async (_req: Request, res: Response) => {
|
||||
try {
|
||||
const state = eventStore.poll();
|
||||
res.status(200).send(state);
|
||||
@@ -57,7 +57,7 @@ export const poll = async (_req, res) => {
|
||||
|
||||
// Create controller for GET request to '/ontime/db'
|
||||
// Returns -
|
||||
export const dbDownload = async (req, res) => {
|
||||
export const dbDownload = async (_req: Request, res: Response) => {
|
||||
const { title } = DataProvider.getProjectData();
|
||||
const fileTitle = title || 'ontime data';
|
||||
|
||||
@@ -77,7 +77,7 @@ export const dbDownload = async (req, res) => {
|
||||
* @param _res
|
||||
* @param options
|
||||
*/
|
||||
async function parseFile(file, _req, _res, options) {
|
||||
async function parseFile(file, _req: Request, _res: Response, options: ExcelImportOptions) {
|
||||
if (!fs.existsSync(file)) {
|
||||
throw new Error('Upload failed');
|
||||
}
|
||||
@@ -85,6 +85,10 @@ async function parseFile(file, _req, _res, options) {
|
||||
return result.data;
|
||||
}
|
||||
|
||||
export type ParsingOptions = {
|
||||
onlyRundown?: 'true' | 'false';
|
||||
};
|
||||
|
||||
/**
|
||||
* parse an uploaded file and apply its parsed objects
|
||||
* @param file
|
||||
@@ -93,7 +97,7 @@ async function parseFile(file, _req, _res, options) {
|
||||
* @param [options]
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
const parseAndApply = async (file, _req, res, options) => {
|
||||
const parseAndApply = async (file, _req: Request, res: Response, options) => {
|
||||
const result = await parseFile(file, _req, res, options);
|
||||
|
||||
runtimeService.stop();
|
||||
@@ -134,7 +138,7 @@ const getNetworkInterfaces = () => {
|
||||
|
||||
// Create controller for GET request to '/ontime/info'
|
||||
// Returns -
|
||||
export const getInfo = async (req: Request, res: Response<GetInfo>) => {
|
||||
export const getInfo = async (_req: Request, res: Response<GetInfo>) => {
|
||||
const { version, serverPort } = DataProvider.getSettings();
|
||||
const osc = DataProvider.getOsc();
|
||||
|
||||
@@ -155,14 +159,14 @@ export const getInfo = async (req: Request, res: Response<GetInfo>) => {
|
||||
|
||||
// Create controller for POST request to '/ontime/aliases'
|
||||
// Returns -
|
||||
export const getAliases = async (req, res) => {
|
||||
export const getAliases = async (_req: Request, res: Response) => {
|
||||
const aliases = DataProvider.getAliases();
|
||||
res.status(200).send(aliases);
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/aliases'
|
||||
// Returns ACK message
|
||||
export const postAliases = async (req, res) => {
|
||||
export const postAliases = async (req: Request, res: Response) => {
|
||||
if (failIsNotArray(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
@@ -178,20 +182,20 @@ export const postAliases = async (req, res) => {
|
||||
await DataProvider.setAliases(newAliases);
|
||||
res.status(200).send(newAliases);
|
||||
} catch (error) {
|
||||
res.status(400).send({ message: error.toString() });
|
||||
res.status(400).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
// Create controller for GET request to '/ontime/userfields'
|
||||
// Returns -
|
||||
export const getUserFields = async (req, res) => {
|
||||
export const getUserFields = async (_req: Request, res: Response) => {
|
||||
const userFields = DataProvider.getUserFields();
|
||||
res.status(200).send(userFields);
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/userfields'
|
||||
// Returns ACK message
|
||||
export const postUserFields = async (req, res) => {
|
||||
export const postUserFields = async (req: Request, res: Response) => {
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
@@ -201,13 +205,13 @@ export const postUserFields = async (req, res) => {
|
||||
await DataProvider.setUserFields(newData);
|
||||
res.status(200).send(newData);
|
||||
} catch (error) {
|
||||
res.status(400).send({ message: error.toString() });
|
||||
res.status(400).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/settings'
|
||||
// Returns -
|
||||
export const getSettings = async (req, res) => {
|
||||
export const getSettings = async (_req: Request, res: Response) => {
|
||||
const settings = DataProvider.getSettings();
|
||||
res.status(200).send(settings);
|
||||
};
|
||||
@@ -227,7 +231,7 @@ function extractPin(value: string | undefined | null, fallback: string | null):
|
||||
|
||||
// Create controller for POST request to '/ontime/settings'
|
||||
// Returns ACK message
|
||||
export const postSettings = async (req, res) => {
|
||||
export const postSettings = async (req: Request, res: Response) => {
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
@@ -264,7 +268,7 @@ export const postSettings = async (req, res) => {
|
||||
await DataProvider.setSettings(newData);
|
||||
res.status(200).send(newData);
|
||||
} catch (error) {
|
||||
res.status(400).send({ message: error.toString() });
|
||||
res.status(400).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -272,7 +276,7 @@ export const postSettings = async (req, res) => {
|
||||
* @description Get view Settings
|
||||
* @method GET
|
||||
*/
|
||||
export const getViewSettings = async (req, res) => {
|
||||
export const getViewSettings = async (_req: Request, res: Response) => {
|
||||
const views = DataProvider.getViewSettings();
|
||||
res.status(200).send(views);
|
||||
};
|
||||
@@ -281,7 +285,7 @@ export const getViewSettings = async (req, res) => {
|
||||
* @description Change view Settings
|
||||
* @method POST
|
||||
*/
|
||||
export const postViewSettings = async (req, res) => {
|
||||
export const postViewSettings = async (req: Request, res: Response) => {
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
@@ -299,20 +303,20 @@ export const postViewSettings = async (req, res) => {
|
||||
await DataProvider.setViewSettings(newData);
|
||||
res.status(200).send(newData);
|
||||
} catch (error) {
|
||||
res.status(400).send({ message: error.toString() });
|
||||
res.status(400).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
// Create controller for GET request to '/ontime/osc'
|
||||
// Returns -
|
||||
export const getOSC = async (req, res) => {
|
||||
export const getOSC = async (_req: Request, res: Response) => {
|
||||
const osc = DataProvider.getOsc();
|
||||
res.status(200).send(osc);
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/osc'
|
||||
// Returns ACK message
|
||||
export const postOSC = async (req, res) => {
|
||||
export const postOSC = async (req: Request, res: Response) => {
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
@@ -333,11 +337,11 @@ export const postOSC = async (req, res) => {
|
||||
|
||||
res.send(oscSettings).status(200);
|
||||
} catch (error) {
|
||||
res.status(400).send({ message: error.toString() });
|
||||
res.status(400).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
export const postOscSubscriptions = async (req, res) => {
|
||||
export const postOscSubscriptions = async (req: Request, res: Response) => {
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
@@ -354,18 +358,18 @@ export const postOscSubscriptions = async (req, res) => {
|
||||
|
||||
res.send(oscSettings).status(200);
|
||||
} catch (error) {
|
||||
res.status(400).send({ message: error.toString() });
|
||||
res.status(400).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
// Create controller for GET request to '/ontime/http'
|
||||
export const getHTTP = async (_req, res: Response<HttpSettings>) => {
|
||||
export const getHTTP = async (_req: Request, res: Response<HttpSettings>) => {
|
||||
const http = DataProvider.getHttp();
|
||||
res.status(200).send(http);
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/http'
|
||||
export const postHTTP = async (req, res) => {
|
||||
export const postHTTP = async (req: Request, res: Response) => {
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
@@ -386,11 +390,11 @@ export const postHTTP = async (req, res) => {
|
||||
|
||||
res.send(httpSettings).status(200);
|
||||
} catch (error) {
|
||||
res.status(400).send({ message: error.toString() });
|
||||
res.status(400).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
export async function patchPartialProjectFile(req, res) {
|
||||
export async function patchPartialProjectFile(req: Request, res: Response) {
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
@@ -414,14 +418,14 @@ export async function patchPartialProjectFile(req, res) {
|
||||
}
|
||||
res.status(200).send();
|
||||
} catch (error) {
|
||||
res.status(400).send({ message: error.toString() });
|
||||
res.status(400).send({ message: String(error) });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* uploads, parses and applies the data from a given file
|
||||
*/
|
||||
export const dbUpload = async (req, res) => {
|
||||
export const dbUpload = async (req: Request, res: Response) => {
|
||||
if (!req.file) {
|
||||
res.status(400).send({ message: 'File not found' });
|
||||
return;
|
||||
@@ -440,7 +444,7 @@ export const dbUpload = async (req, res) => {
|
||||
* uploads and parses an excel file
|
||||
* @returns parsed result
|
||||
*/
|
||||
export async function previewExcel(req, res) {
|
||||
export async function previewExcel(req, res: Response) {
|
||||
if (!req.file) {
|
||||
res.status(400).send({ message: 'File not found' });
|
||||
return;
|
||||
@@ -452,7 +456,7 @@ export async function previewExcel(req, res) {
|
||||
const data = await parseFile(file, req, res, options);
|
||||
res.status(200).send(data);
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +479,7 @@ export const postNew: RequestHandler = async (req, res) => {
|
||||
await deleteAllEvents();
|
||||
res.status(201).send(newData);
|
||||
} catch (error) {
|
||||
res.status(400).send({ message: error.toString() });
|
||||
res.status(400).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -497,7 +501,7 @@ export const listProjects: RequestHandler = async (_, res: Response<ProjectFileL
|
||||
lastLoadedProject: lastLoadedProjectName,
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -523,7 +527,7 @@ export const loadProject: RequestHandler = async (req, res) => {
|
||||
message: `Loaded project ${filename}`,
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -537,7 +541,7 @@ export const loadProject: RequestHandler = async (req, res) => {
|
||||
* a 409 status if there are validation errors,
|
||||
* or a 500 status with an error message in case of an exception.
|
||||
*/
|
||||
export const duplicateProjectFile: RequestHandler = async (req, res) => {
|
||||
export const duplicateProjectFile: RequestHandler = async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { filename } = req.params;
|
||||
const { newFilename } = req.body;
|
||||
@@ -557,7 +561,7 @@ export const duplicateProjectFile: RequestHandler = async (req, res) => {
|
||||
message: `Duplicated project ${filename} to ${newFilename}`,
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -571,7 +575,7 @@ export const duplicateProjectFile: RequestHandler = async (req, res) => {
|
||||
* a 409 status if there are validation errors,
|
||||
* or a 500 status with an error message in case of an exception.
|
||||
*/
|
||||
export const renameProjectFile: RequestHandler = async (req, res) => {
|
||||
export const renameProjectFile: RequestHandler = async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { newFilename } = req.body;
|
||||
const { filename } = req.params;
|
||||
@@ -599,7 +603,7 @@ export const renameProjectFile: RequestHandler = async (req, res) => {
|
||||
message: `Renamed project ${filename} to ${newFilename}`,
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -612,7 +616,7 @@ export const renameProjectFile: RequestHandler = async (req, res) => {
|
||||
* a 409 status if there are validation errors,
|
||||
* or a 500 status with an error message in case of an exception.
|
||||
*/
|
||||
export const createProjectFile: RequestHandler = async (req, res) => {
|
||||
export const createProjectFile: RequestHandler = async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { filename } = req.body;
|
||||
|
||||
@@ -624,14 +628,13 @@ export const createProjectFile: RequestHandler = async (req, res) => {
|
||||
return res.status(409).send({ message: errors.join(', ') });
|
||||
}
|
||||
|
||||
console.log(`----------------> Creating directory createProjectFile: ${projectFilePath}`);
|
||||
await writeFile(projectFilePath, JSON.stringify(dbModel));
|
||||
|
||||
res.status(200).send({
|
||||
message: `Created project ${filename}`,
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -645,7 +648,7 @@ export const createProjectFile: RequestHandler = async (req, res) => {
|
||||
* a 409 status if there are validation errors,
|
||||
* or a 500 status with an error message in case of an exception.
|
||||
*/
|
||||
export const deleteProjectFile: RequestHandler = async (req, res) => {
|
||||
export const deleteProjectFile: RequestHandler = async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { filename } = req.params;
|
||||
|
||||
@@ -669,7 +672,7 @@ export const deleteProjectFile: RequestHandler = async (req, res) => {
|
||||
message: `Deleted project ${filename}`,
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -678,7 +681,7 @@ export const deleteProjectFile: RequestHandler = async (req, res) => {
|
||||
* @description SETP-1 POST Client Secrect
|
||||
* @returns parsed result
|
||||
*/
|
||||
export async function uploadSheetClientFile(req, res) {
|
||||
export async function uploadSheetClientFile(req, res: Response) {
|
||||
if (!req.file.path) {
|
||||
res.status(400).send({ message: 'File not found' });
|
||||
return;
|
||||
@@ -688,7 +691,7 @@ export async function uploadSheetClientFile(req, res) {
|
||||
await sheet.saveClientSecrets(client);
|
||||
res.status(200).send('OK');
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
fs.unlink(req.file.path, (err) => {
|
||||
if (err) logger.error(LogOrigin.Server, err.message);
|
||||
@@ -698,7 +701,7 @@ export async function uploadSheetClientFile(req, res) {
|
||||
/**
|
||||
* @description STEP-1 GET Client Secrect status
|
||||
*/
|
||||
export const getClientSecrect = async (req, res) => {
|
||||
export const getClientSecrect = async (req: Request, res: Response) => {
|
||||
try {
|
||||
const clientSecrectExists = await sheet.testClientSecret();
|
||||
if (clientSecrectExists) {
|
||||
@@ -707,31 +710,31 @@ export const getClientSecrect = async (req, res) => {
|
||||
res.status(500).send({ message: 'The Client ID does not exist' });
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @description STEP-2 GET sheet authentication url
|
||||
*/
|
||||
export async function getAuthenticationUrl(req, res) {
|
||||
export async function getAuthenticationUrl(_req: Request, res: Response) {
|
||||
try {
|
||||
const authUrl = await sheet.openAuthServer();
|
||||
res.status(200).send(authUrl);
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description STEP-2 GET sheet authentication status
|
||||
*/
|
||||
export const getAuthentication = async (req, res) => {
|
||||
export const getAuthentication = async (_req: Request, res: Response) => {
|
||||
try {
|
||||
await sheet.testAuthentication();
|
||||
res.status(200).send();
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -739,7 +742,7 @@ export const getAuthentication = async (req, res) => {
|
||||
* @description STEP-3 POST sheet id
|
||||
* @returns list of worksheets
|
||||
*/
|
||||
export const postId = async (req, res) => {
|
||||
export const postId = async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { id } = req.body;
|
||||
if (id.lenght < 40) {
|
||||
@@ -748,20 +751,20 @@ export const postId = async (req, res) => {
|
||||
const state = await sheet.testSheetId(id);
|
||||
res.status(200).send(state);
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @description STEP-4 POST worksheet
|
||||
*/
|
||||
export const postWorksheet = async (req, res) => {
|
||||
export const postWorksheet = async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { worksheet, id } = req.body;
|
||||
const state = await sheet.testWorksheet(worksheet, id);
|
||||
res.status(200).send(state);
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -769,25 +772,25 @@ export const postWorksheet = async (req, res) => {
|
||||
* @description STEP-5 POST download undown to sheet
|
||||
* @returns parsed result
|
||||
*/
|
||||
export async function pullSheet(req, res) {
|
||||
export async function pullSheet(req: Request, res: Response) {
|
||||
try {
|
||||
const { id, options } = req.body;
|
||||
const data = await sheet.pull(id, options);
|
||||
res.status(200).send(data);
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description STEP-5 POST upload rundown to sheet
|
||||
*/
|
||||
export async function pushSheet(req, res) {
|
||||
export async function pushSheet(req: Request, res: Response) {
|
||||
try {
|
||||
const { id, options } = req.body;
|
||||
await sheet.push(id, options);
|
||||
res.status(200).send();
|
||||
} catch (error) {
|
||||
res.status(500).send({ message: error.toString() });
|
||||
res.status(500).send({ message: String(error) });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ export const validateProjectCreate = [
|
||||
*
|
||||
*/
|
||||
export const validateProjectFiles = (projectFiles: { filename?: string; newFilename?: string }): Array<string> => {
|
||||
const errors = [];
|
||||
const errors: string[] = [];
|
||||
|
||||
if (projectFiles.filename) {
|
||||
const projectFilePath = join(uploadsFolderPath, projectFiles.filename);
|
||||
|
||||
@@ -35,7 +35,7 @@ const populateDb = () => {
|
||||
* @param adapterToUse
|
||||
* @return {Promise<number|*>}
|
||||
*/
|
||||
const parseDb = async (fileToRead, adapterToUse) => {
|
||||
const parseDb = async (fileToRead: string, adapterToUse: Low<DatabaseModel>) => {
|
||||
if (validateFile(fileToRead)) {
|
||||
await adapterToUse.read();
|
||||
} else {
|
||||
|
||||
@@ -81,7 +81,7 @@ export class TimerService {
|
||||
const newState = runtimeState.getState();
|
||||
|
||||
// handle end action if there was a timer playing
|
||||
if (newState.timer.playback === Playback.Play) {
|
||||
if (newState.timer.playback === Playback.Play && newState.eventNow) {
|
||||
if (newState.eventNow.endAction === EndAction.Stop) {
|
||||
runtimeState.stop();
|
||||
} else if (newState.eventNow.endAction === EndAction.LoadNext) {
|
||||
|
||||
@@ -860,7 +860,7 @@ describe('getRollTimers()', () => {
|
||||
publicIndex: null,
|
||||
nextIndex: 0,
|
||||
publicNextIndex: 4,
|
||||
timeToNext: dayInMs - now + eventlist[0].timeStart,
|
||||
timeToNext: dayInMs - now + eventlist[0].timeStart!,
|
||||
nextEvent: eventlist[0],
|
||||
nextPublicEvent: eventlist[4],
|
||||
currentEvent: null,
|
||||
@@ -887,7 +887,7 @@ describe('getRollTimers()', () => {
|
||||
publicIndex: null,
|
||||
nextIndex: 0,
|
||||
publicNextIndex: 0,
|
||||
timeToNext: dayInMs - now + singleEventList[0].timeStart,
|
||||
timeToNext: dayInMs - now + singleEventList[0].timeStart!,
|
||||
nextEvent: singleEventList[0],
|
||||
nextPublicEvent: singleEventList[0],
|
||||
currentEvent: null,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { MaybeNumber } from 'ontime-types';
|
||||
import { millisToString, removeLeadingZero } from 'ontime-utils';
|
||||
|
||||
// any value inside double curly braces {{val}}
|
||||
const placeholderRegex = /{{(.*?)}}/g;
|
||||
|
||||
function formatDisplayFromString(value: string, hideZero = false): string {
|
||||
let valueInNumber = null;
|
||||
let valueInNumber: MaybeNumber = null;
|
||||
|
||||
if (value !== 'null') {
|
||||
const parsedValue = Number(value);
|
||||
@@ -48,7 +49,7 @@ export function parseTemplateNested(template: string, state: object, humanReadab
|
||||
for (const match of matches) {
|
||||
const variableName = match[1];
|
||||
const variableParts = variableName.split('.');
|
||||
let value = undefined;
|
||||
let value: string | undefined = undefined;
|
||||
|
||||
if (variableParts[0] === 'human') {
|
||||
const lookupKey = variableParts[1];
|
||||
|
||||
@@ -4,7 +4,7 @@ import { throttle } from '../../utils/throttle.js';
|
||||
|
||||
import type { PublishFn } from '../../stores/EventStore.js';
|
||||
|
||||
let instance;
|
||||
let instance: MessageService | null = null;
|
||||
|
||||
class MessageService {
|
||||
timer: TimerMessage;
|
||||
@@ -56,7 +56,7 @@ class MessageService {
|
||||
|
||||
init(publish: PublishFn) {
|
||||
this.publish = publish;
|
||||
this.throttledSet = throttle((key, value) => this.publish(key, value), 100);
|
||||
this.throttledSet = throttle((key, value) => this.publish?.(key, value), 100);
|
||||
}
|
||||
|
||||
getState(): MessageState {
|
||||
|
||||
@@ -104,7 +104,8 @@ export async function editEvent(patch: Partial<OntimeEvent> | Partial<OntimeBloc
|
||||
}
|
||||
|
||||
const scopedMutation = cache.mutateCache(cache.edit);
|
||||
const { newEvent } = await scopedMutation({ patch, eventId: patch.id });
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know patch has an id
|
||||
const { newEvent } = await scopedMutation({ patch, eventId: patch.id! });
|
||||
|
||||
notifyChanges({ timer: [patch.id], external: true });
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ export function get(): Readonly<RundownCache> {
|
||||
}
|
||||
|
||||
type CommonParams = { persistedRundown: OntimeRundown };
|
||||
type MutationParams<T> = T & Partial<CommonParams>;
|
||||
type MutationParams<T> = T & CommonParams;
|
||||
type MutatingReturn = {
|
||||
newRundown: OntimeRundown;
|
||||
newEvent?: OntimeRundownEntry;
|
||||
|
||||
@@ -166,6 +166,9 @@ class RuntimeService {
|
||||
*/
|
||||
startById(eventId: string): boolean {
|
||||
const event = getEventWithId(eventId);
|
||||
if (!event) {
|
||||
return false;
|
||||
}
|
||||
const success = this.loadEvent(event);
|
||||
if (success) {
|
||||
this.start();
|
||||
@@ -180,6 +183,9 @@ class RuntimeService {
|
||||
*/
|
||||
startByIndex(eventIndex: number): boolean {
|
||||
const event = getEventAtIndex(eventIndex);
|
||||
if (!event) {
|
||||
return false;
|
||||
}
|
||||
const success = this.loadEvent(event);
|
||||
if (success) {
|
||||
this.start();
|
||||
@@ -194,6 +200,9 @@ class RuntimeService {
|
||||
*/
|
||||
startByCue(cue: string): boolean {
|
||||
const event = getEventWithCue(cue);
|
||||
if (!event) {
|
||||
return false;
|
||||
}
|
||||
const success = this.loadEvent(event);
|
||||
if (success) {
|
||||
this.start();
|
||||
@@ -208,6 +217,9 @@ class RuntimeService {
|
||||
*/
|
||||
loadById(eventId: string): boolean {
|
||||
const event = getEventWithId(eventId);
|
||||
if (!event) {
|
||||
return false;
|
||||
}
|
||||
const success = this.loadEvent(event);
|
||||
return success;
|
||||
}
|
||||
@@ -219,6 +231,9 @@ class RuntimeService {
|
||||
*/
|
||||
loadByIndex(eventIndex: number): boolean {
|
||||
const event = getEventAtIndex(eventIndex);
|
||||
if (!event) {
|
||||
return false;
|
||||
}
|
||||
const success = this.loadEvent(event);
|
||||
return success;
|
||||
}
|
||||
@@ -230,6 +245,9 @@ class RuntimeService {
|
||||
*/
|
||||
loadByCue(cue: string): boolean {
|
||||
const event = getEventWithCue(cue);
|
||||
if (!event) {
|
||||
return false;
|
||||
}
|
||||
const success = this.loadEvent(event);
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,11 @@ export const normaliseEndTime = (start: number, end: number) => (end < start ? e
|
||||
*/
|
||||
export function getExpectedFinish(state: RuntimeState): MaybeNumber {
|
||||
const { startedAt, finishedAt, duration, addedTime } = state.timer;
|
||||
|
||||
if (state.eventNow === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { timerType, timeEnd } = state.eventNow;
|
||||
const { pausedAt } = state._timer;
|
||||
const { clock } = state;
|
||||
@@ -33,7 +38,8 @@ export function getExpectedFinish(state: RuntimeState): MaybeNumber {
|
||||
}
|
||||
|
||||
// handle events that finish the day after
|
||||
const expectedFinish = startedAt + duration + addedTime + pausedTime;
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- duration exists if ther eis a timer
|
||||
const expectedFinish = startedAt + duration! + addedTime + pausedTime;
|
||||
if (expectedFinish > dayInMs) {
|
||||
return expectedFinish - dayInMs;
|
||||
}
|
||||
|
||||
@@ -19,13 +19,13 @@ export function getAppDataPath(): string {
|
||||
|
||||
switch (process.platform) {
|
||||
case 'darwin': {
|
||||
return path.join(process.env.HOME, 'Library', 'Application Support', 'Ontime');
|
||||
return path.join(process.env.HOME!, 'Library', 'Application Support', 'Ontime');
|
||||
}
|
||||
case 'win32': {
|
||||
return path.join(process.env.APPDATA, 'Ontime');
|
||||
return path.join(process.env.APPDATA!, 'Ontime');
|
||||
}
|
||||
case 'linux': {
|
||||
return path.join(process.env.HOME, '.Ontime');
|
||||
return path.join(process.env.HOME!, '.Ontime');
|
||||
}
|
||||
default: {
|
||||
throw new Error('Could not resolve public folder for platform');
|
||||
|
||||
@@ -77,7 +77,7 @@ describe('mutation on runtimeState', () => {
|
||||
// 1. Load event
|
||||
load(mockEvent, [mockEvent]);
|
||||
let newState = getState();
|
||||
expect(newState.eventNow.id).toBe(mockEvent.id);
|
||||
expect(newState.eventNow?.id).toBe(mockEvent.id);
|
||||
expect(newState.timer.playback).toBe(Playback.Armed);
|
||||
expect(newState.clock).not.toBe(666);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
export function throttle<T extends any[], U>(cb: (...args: T) => U, delay: number) {
|
||||
let shouldWait = false;
|
||||
let waitingArgs;
|
||||
let waitingArgs: T | null = null;
|
||||
const timeoutFunc = () => {
|
||||
if (waitingArgs == null) {
|
||||
shouldWait = false;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import multer from 'multer';
|
||||
import { Request } from 'express';
|
||||
import multer, { FileFilterCallback } from 'multer';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
@@ -6,12 +7,12 @@ import { EXCEL_MIME, JSON_MIME } from './parser.js';
|
||||
import { ensureDirectory } from './fileManagement.js';
|
||||
import { getAppDataPath } from '../setup.js';
|
||||
|
||||
function generateNewFileName(filePath, callback) {
|
||||
function generateNewFileName(filePath: string, callback: (newName: string) => void) {
|
||||
const baseName = path.basename(filePath, path.extname(filePath));
|
||||
const extension = path.extname(filePath);
|
||||
let counter = 1;
|
||||
|
||||
const checkExistence = (newPath) => {
|
||||
const checkExistence = (newPath: string) => {
|
||||
fs.access(newPath, fs.constants.F_OK, (err) => {
|
||||
if (err) {
|
||||
// File with the new name does not exist, use this name
|
||||
@@ -64,7 +65,7 @@ const storage = multer.diskStorage({
|
||||
* @argument file - reference to file
|
||||
* @return {boolean} - file allowed
|
||||
*/
|
||||
const filterAllowed = (req, file, cb) => {
|
||||
const filterAllowed = (_req: Request, file: Express.Multer.File, cb: FileFilterCallback) => {
|
||||
if (file.mimetype.includes(JSON_MIME) || file.mimetype.includes(EXCEL_MIME)) {
|
||||
cb(null, true);
|
||||
} else {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"experimentalDecorators": true,
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
"src/**/*.ts",
|
||||
"src/**/*.js",
|
||||
],
|
||||
"exclude": ["node_modules", "build"],
|
||||
}
|
||||
|
||||
Generated
+18
@@ -304,9 +304,15 @@ importers:
|
||||
specifier: ^8.13.0
|
||||
version: 8.13.0
|
||||
devDependencies:
|
||||
'@types/cors':
|
||||
specifier: ^2.8.17
|
||||
version: 2.8.17
|
||||
'@types/express':
|
||||
specifier: ^4.17.17
|
||||
version: 4.17.17
|
||||
'@types/multer':
|
||||
specifier: ^1.4.11
|
||||
version: 1.4.11
|
||||
'@types/node':
|
||||
specifier: ^18.11.18
|
||||
version: 18.11.18
|
||||
@@ -3161,6 +3167,12 @@ packages:
|
||||
'@types/node': 18.19.3
|
||||
dev: true
|
||||
|
||||
/@types/cors@2.8.17:
|
||||
resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==}
|
||||
dependencies:
|
||||
'@types/node': 18.19.3
|
||||
dev: true
|
||||
|
||||
/@types/debug@4.1.12:
|
||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||
dependencies:
|
||||
@@ -3252,6 +3264,12 @@ packages:
|
||||
resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==}
|
||||
dev: true
|
||||
|
||||
/@types/multer@1.4.11:
|
||||
resolution: {integrity: sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==}
|
||||
dependencies:
|
||||
'@types/express': 4.17.17
|
||||
dev: true
|
||||
|
||||
/@types/node-osc@6.0.2:
|
||||
resolution: {integrity: sha512-/TxCH+NlDoI3hFA6b2O91dpnPAqBDkLb2HEIv5hMVdKnCiWTdJJv2sVnQdX38sBgnals8TjCQEGii+OcMVf2fg==}
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user