diff --git a/apps/client/src/common/components/error-boundary/ErrorBoundary.jsx b/apps/client/src/common/components/error-boundary/ErrorBoundary.jsx
index bda907ddc..e6cfeb918 100644
--- a/apps/client/src/common/components/error-boundary/ErrorBoundary.jsx
+++ b/apps/client/src/common/components/error-boundary/ErrorBoundary.jsx
@@ -1,10 +1,9 @@
// skipcq: JS-C1003 - sentry does not expose itself as an ES Module.
import * as Sentry from '@sentry/react';
-/* eslint-disable react/destructuring-assignment */
import React from 'react';
-import { hasConnected, reconnectAttempts } from '../../../common/utils/socket';
import { runtimeStore } from '../../stores/runtime';
+import { getConnectionState, getReconnectAttempts } from '../../utils/socket';
import style from './ErrorBoundary.module.scss';
@@ -37,7 +36,7 @@ class ErrorBoundary extends React.Component {
scope.setExtras({
error,
store: appState,
- hasSocket: { hasConnected, reconnectAttempts },
+ hasSocket: { hasConnected: getConnectionState(), reconnectAttempts: getReconnectAttempts() },
});
const eventId = Sentry.captureException(error);
this.setState({ eventId, info });
diff --git a/apps/client/src/common/components/view-params-editor/ViewParamsSection.tsx b/apps/client/src/common/components/view-params-editor/ViewParamsSection.tsx
index fe1b73e3c..28e5ea134 100644
--- a/apps/client/src/common/components/view-params-editor/ViewParamsSection.tsx
+++ b/apps/client/src/common/components/view-params-editor/ViewParamsSection.tsx
@@ -64,8 +64,8 @@ function SectionContents({ options, collapsed }: SectionContentsProps) {
function HiddenContents({ options }: { options: ParamField[] }) {
return (
<>
- {options.map((option, index) => {
- return ;
+ {options.map((option) => {
+ return ;
})}
>
);
diff --git a/apps/client/src/common/utils/socket.ts b/apps/client/src/common/utils/socket.ts
index b000f935f..3c1068048 100644
--- a/apps/client/src/common/utils/socket.ts
+++ b/apps/client/src/common/utils/socket.ts
@@ -51,8 +51,10 @@ const socketConfig = {
offlineAttemptsThreshold: 2, // when we consider the client disconnected
} as const;
-export let hasConnected = false;
-export let reconnectAttempts = 0;
+export const getConnectionState = () => hasConnected;
+export const getReconnectAttempts = () => reconnectAttempts;
+let hasConnected = false;
+let reconnectAttempts = 0;
export const connectSocket = () => {
websocket = new WebSocket(websocketUrl);
diff --git a/apps/client/src/views/project-info/ProjectInfo.tsx b/apps/client/src/views/project-info/ProjectInfo.tsx
index bae7d896a..fed8b32c1 100644
--- a/apps/client/src/views/project-info/ProjectInfo.tsx
+++ b/apps/client/src/views/project-info/ProjectInfo.tsx
@@ -80,6 +80,7 @@ function ProjectInfo({ projectData, isMirrored }: ProjectInfoData) {
{projectData.custom.map((info, idx) => {
const hasUrl = Boolean(info.url);
return (
+ // oxlint-disable-next-line react/no-array-index-key - we only have the index to go of here
{hasUrl && (
diff --git a/apps/server/src/api-data/automation/automation.router.ts b/apps/server/src/api-data/automation/automation.router.ts
index a46ac684e..5d91fc683 100644
--- a/apps/server/src/api-data/automation/automation.router.ts
+++ b/apps/server/src/api-data/automation/automation.router.ts
@@ -1,4 +1,4 @@
-import express from 'express';
+import express, { Router } from 'express';
import { paramsWithId } from '../validation-utils/validationFunction.js';
import {
@@ -21,7 +21,7 @@ import {
validateTriggerPatch,
} from './automation.validation.js';
-export const router = express.Router();
+export const router: Router = express.Router();
router.get('/', getAutomationSettings);
router.post('/', validateAutomationSettings, postAutomationSettings);
diff --git a/apps/server/src/api-data/custom-fields/customFields.router.ts b/apps/server/src/api-data/custom-fields/customFields.router.ts
index e955ae2d7..2bb989a9d 100644
--- a/apps/server/src/api-data/custom-fields/customFields.router.ts
+++ b/apps/server/src/api-data/custom-fields/customFields.router.ts
@@ -1,5 +1,5 @@
import express from 'express';
-import type { Request, Response } from 'express';
+import type { Request, Response, Router } from 'express';
import { CustomField, CustomFields, ErrorResponse } from 'ontime-types';
import { getErrorMessage } from 'ontime-utils';
@@ -8,12 +8,12 @@ import { getProjectCustomFields } from '../rundown/rundown.dao.js';
import { createCustomField, deleteCustomField, editCustomField } from '../rundown/rundown.service.js';
import { validateCustomField, validateDeleteCustomField, validateEditCustomField } from './customFields.validation.js';
-export const router = express.Router();
+export const router: Router = express.Router();
/**
* Gets all the custom fields for the project
*/
-router.get('/', async (_req: Request, res: Response
) => {
+router.get('/', (_req: Request, res: Response) => {
const customFields = getProjectCustomFields();
res.status(200).json(customFields);
});
diff --git a/apps/server/src/api-data/custom-views/customViews.router.ts b/apps/server/src/api-data/custom-views/customViews.router.ts
index 50e9fe2a8..7f220b346 100644
--- a/apps/server/src/api-data/custom-views/customViews.router.ts
+++ b/apps/server/src/api-data/custom-views/customViews.router.ts
@@ -1,5 +1,5 @@
import express from 'express';
-import type { Request, Response } from 'express';
+import type { Request, Response, Router } from 'express';
import { type CustomViewsListResponse, type ErrorResponse, type MessageResponse } from 'ontime-types';
import { handleCustomViewsError } from './customViews.errors.js';
@@ -13,7 +13,7 @@ import {
} from './customViews.service.js';
import { validateCustomViewSlugParam } from './customViews.validation.js';
-export const router = express.Router();
+export const router: Router = express.Router();
router.get('/', async (_req: Request, res: Response) => {
try {
diff --git a/apps/server/src/api-data/db/db.router.ts b/apps/server/src/api-data/db/db.router.ts
index 3ce4b1d3f..cdac334c3 100644
--- a/apps/server/src/api-data/db/db.router.ts
+++ b/apps/server/src/api-data/db/db.router.ts
@@ -1,4 +1,4 @@
-import express from 'express';
+import express, { Router } from 'express';
import {
createProjectFile,
@@ -24,7 +24,7 @@ import {
validateQuickProject,
} from './db.validation.js';
-export const router = express.Router();
+export const router: Router = express.Router();
router.get('/', currentProjectDownload);
router.post('/download', validateFilenameBody, projectDownload);
diff --git a/apps/server/src/api-data/excel/excel.router.ts b/apps/server/src/api-data/excel/excel.router.ts
index fd08c950b..43dfc0223 100644
--- a/apps/server/src/api-data/excel/excel.router.ts
+++ b/apps/server/src/api-data/excel/excel.router.ts
@@ -1,11 +1,12 @@
import express from 'express';
-import type { Request, Response } from 'express';
+import type { Request, Response, Router } from 'express';
import type {
ErrorResponse,
SpreadsheetPreviewResponse,
SpreadsheetWorksheetMetadata,
SpreadsheetWorksheetOptions,
} from 'ontime-types';
+import { getErrorMessage } from 'ontime-utils';
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';
import { getProjectCustomFields } from '../rundown/rundown.dao.js';
@@ -19,7 +20,7 @@ import {
validateWorksheetMetadataRequest,
} from './excel.validation.js';
-export const router = express.Router();
+export const router: Router = express.Router();
router.post(
'/upload',
@@ -32,7 +33,8 @@ router.post(
const worksheetOptions = await readExcelFile(filePath);
res.status(200).send(worksheetOptions);
} catch (error) {
- res.status(500).send({ message: String(error) });
+ const message = getErrorMessage(error);
+ res.status(500).send({ message });
}
},
);
@@ -46,7 +48,8 @@ router.post(
const data = generateRundownPreview(options);
res.status(200).send(data);
} catch (error) {
- res.status(500).send({ message: String(error) });
+ const message = getErrorMessage(error);
+ res.status(500).send({ message });
}
},
);
@@ -60,7 +63,8 @@ router.post(
const data = getWorksheetMetadata(worksheet);
res.status(200).send(data);
} catch (error) {
- res.status(500).send({ message: String(error) });
+ const message = getErrorMessage(error);
+ res.status(500).send({ message });
}
},
);
@@ -75,7 +79,7 @@ router.get('/:rundownId/export', validateRundownExport, (req: Request, res: Resp
res.setHeader('Content-Type', EXCEL_MIME);
res.setHeader('Content-Length', buffer.length.toString());
res.status(200).send(buffer);
- } catch (error) {
+ } catch (_error) {
res.status(500).send({ message: 'Failed to generate Excel file' });
}
});
diff --git a/apps/server/src/api-data/index.ts b/apps/server/src/api-data/index.ts
index ecbf5e7e3..66803ff1d 100644
--- a/apps/server/src/api-data/index.ts
+++ b/apps/server/src/api-data/index.ts
@@ -1,4 +1,4 @@
-import express from 'express';
+import express, { Router } from 'express';
import { router as assetsRouter } from './assets/assets.router.js';
import { router as automationsRouter } from './automation/automation.router.js';
@@ -15,7 +15,7 @@ import { router as sheetsRouter } from './sheets/sheets.router.js';
import { router as urlPresetsRouter } from './url-presets/urlPresets.router.js';
import { router as viewSettingsRouter } from './view-settings/viewSettings.router.js';
-export const appRouter = express.Router();
+export const appRouter: Router = express.Router();
appRouter.use('/automations', automationsRouter);
appRouter.use('/custom-fields', customFieldsRouter);
diff --git a/apps/server/src/api-data/project-data/projectData.router.ts b/apps/server/src/api-data/project-data/projectData.router.ts
index 4e2951951..117f0bd8d 100644
--- a/apps/server/src/api-data/project-data/projectData.router.ts
+++ b/apps/server/src/api-data/project-data/projectData.router.ts
@@ -1,5 +1,5 @@
import express from 'express';
-import type { Request, Response } from 'express';
+import type { Request, Response, Router } from 'express';
import type { ErrorResponse, ProjectData } from 'ontime-types';
import { getErrorMessage } from 'ontime-utils';
@@ -9,7 +9,7 @@ import { uploadImageFile } from '../db/db.middleware.js';
import * as projectDao from './projectData.dao.js';
import { projectSanitiser } from './projectData.validation.js';
-export const router = express.Router();
+export const router: Router = express.Router();
router.get('/', (_req: Request, res: Response) => {
res.status(200).json(projectDao.getProjectData());
diff --git a/apps/server/src/api-data/report/report.router.ts b/apps/server/src/api-data/report/report.router.ts
index 62864c033..94b35dc42 100644
--- a/apps/server/src/api-data/report/report.router.ts
+++ b/apps/server/src/api-data/report/report.router.ts
@@ -1,10 +1,10 @@
import express from 'express';
-import type { Request, Response } from 'express';
+import type { Request, Response, Router } from 'express';
import { paramsWithId } from '../validation-utils/validationFunction.js';
import * as report from './report.service.js';
-export const router = express.Router();
+export const router: Router = express.Router();
router.get('/', (_req: Request, res: Response) => {
res.status(200).json(report.generate());
diff --git a/apps/server/src/api-data/rundown/rundown.router.ts b/apps/server/src/api-data/rundown/rundown.router.ts
index 996900c59..46e33c675 100644
--- a/apps/server/src/api-data/rundown/rundown.router.ts
+++ b/apps/server/src/api-data/rundown/rundown.router.ts
@@ -1,4 +1,4 @@
-import type { Request, Response } from 'express';
+import type { Request, Response, Router } from 'express';
import express from 'express';
import { ErrorResponse, OntimeEntry, ProjectRundownsList, Rundown } from 'ontime-types';
import { getErrorMessage } from 'ontime-utils';
@@ -35,7 +35,7 @@ import {
validateRundownMutation,
} from './rundown.validation.js';
-export const router = express.Router();
+export const router: Router = express.Router();
// #region operations on project rundowns =========================
diff --git a/apps/server/src/api-data/session/session.router.ts b/apps/server/src/api-data/session/session.router.ts
index d4f98c7dd..7627d3058 100644
--- a/apps/server/src/api-data/session/session.router.ts
+++ b/apps/server/src/api-data/session/session.router.ts
@@ -1,12 +1,12 @@
import express from 'express';
-import type { Request, Response } from 'express';
+import type { Request, Response, Router } from 'express';
import type { ErrorResponse, GetInfo, GetUrl, SessionStats } from 'ontime-types';
import { getErrorMessage } from 'ontime-utils';
import * as sessionService from './session.service.js';
import { validateGenerateUrl } from './session.validation.js';
-export const router = express.Router();
+export const router: Router = express.Router();
router.get('/', async (_req: Request, res: Response) => {
try {
@@ -18,9 +18,9 @@ router.get('/', async (_req: Request, res: Response) => {
+router.get('/info', (_req: Request, res: Response) => {
try {
- const info = await sessionService.getInfo();
+ const info = sessionService.getInfo();
res.status(200).send(info);
} catch (error) {
const message = getErrorMessage(error);
diff --git a/apps/server/src/api-data/session/session.service.ts b/apps/server/src/api-data/session/session.service.ts
index 884b0cee9..bf67c32bd 100644
--- a/apps/server/src/api-data/session/session.service.ts
+++ b/apps/server/src/api-data/session/session.service.ts
@@ -37,7 +37,7 @@ export async function getSessionStats(): Promise {
/**
* Adds business logic to gathering data for the info endpoint
*/
-export async function getInfo(): Promise {
+export function getInfo(): GetInfo {
const { version } = getDataProvider().getSettings();
const { port } = portManager.getPort();
diff --git a/apps/server/src/api-data/settings/settings.router.ts b/apps/server/src/api-data/settings/settings.router.ts
index 767c72e06..51cbb3d09 100644
--- a/apps/server/src/api-data/settings/settings.router.ts
+++ b/apps/server/src/api-data/settings/settings.router.ts
@@ -1,5 +1,5 @@
import express from 'express';
-import type { Request, Response } from 'express';
+import type { Request, Response, Router } from 'express';
import { matchedData } from 'express-validator';
import { deepEqual } from 'fast-equals';
import { ErrorResponse, PortInfo, RefetchKey, Settings } from 'ontime-types';
@@ -11,7 +11,7 @@ import { portManager } from '../../classes/port-manager/PortManager.js';
import * as appState from '../../services/app-state-service/AppStateService.js';
import { validateSettings, validateWelcomeDialog, validateServerPort } from './settings.validation.js';
-export const router = express.Router();
+export const router: Router = express.Router();
router.post('/welcomedialog', validateWelcomeDialog, async (req: Request, res: Response) => {
const show = await appState.setShowWelcomeDialog(req.body.show);
diff --git a/apps/server/src/api-data/sheets/sheets.controller.ts b/apps/server/src/api-data/sheets/sheets.controller.ts
index e8ac59cd8..2ee1f2255 100644
--- a/apps/server/src/api-data/sheets/sheets.controller.ts
+++ b/apps/server/src/api-data/sheets/sheets.controller.ts
@@ -56,7 +56,7 @@ export async function requestConnection(
/**
* Returns the current Google Sheets authentication status for this server session.
*/
-export async function verifyAuthentication(
+export function verifyAuthentication(
_req: Request,
res: Response<{ authenticated: AuthenticationStatus } | ErrorResponse>,
) {
@@ -72,7 +72,7 @@ export async function verifyAuthentication(
/**
* Clears the current Google Sheets authentication session.
*/
-export async function revokeAuthentication(
+export function revokeAuthentication(
_req: Request,
res: Response<{ authenticated: AuthenticationStatus } | ErrorResponse>,
) {
diff --git a/apps/server/src/api-data/sheets/sheets.router.ts b/apps/server/src/api-data/sheets/sheets.router.ts
index d91314ef9..c6c1abe28 100644
--- a/apps/server/src/api-data/sheets/sheets.router.ts
+++ b/apps/server/src/api-data/sheets/sheets.router.ts
@@ -2,7 +2,7 @@
* This is a feature specific router for integration with google sheets
*/
-import express from 'express';
+import express, { Router } from 'express';
import {
getWorksheetMetadataFromSheet,
@@ -21,7 +21,7 @@ import {
validateWorksheetMetadata,
} from './sheets.validation.js';
-export const router = express.Router();
+export const router: Router = express.Router();
router.get('/connect', verifyAuthentication);
router.post('/:sheetId/connect', uploadClientSecret, validateRequestConnection, requestConnection);
diff --git a/apps/server/src/api-data/url-presets/urlPresets.router.ts b/apps/server/src/api-data/url-presets/urlPresets.router.ts
index 6de6fd9a0..81d3ac7f1 100644
--- a/apps/server/src/api-data/url-presets/urlPresets.router.ts
+++ b/apps/server/src/api-data/url-presets/urlPresets.router.ts
@@ -1,5 +1,5 @@
import express from 'express';
-import type { Request, Response } from 'express';
+import type { Request, Response, Router } from 'express';
import { type ErrorResponse, RefetchKey, type URLPreset } from 'ontime-types';
import { getErrorMessage } from 'ontime-utils';
@@ -7,7 +7,7 @@ import { sendRefetch } from '../../adapters/WebsocketAdapter.js';
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';
import { validateNewPreset, validatePresetParam, validateUpdatePreset } from './urlPresets.validation.js';
-export const router = express.Router();
+export const router: Router = express.Router();
router.get('/', (_req: Request, res: Response) => {
const presets = getDataProvider().getUrlPresets();
diff --git a/apps/server/src/api-data/view-settings/viewSettings.router.ts b/apps/server/src/api-data/view-settings/viewSettings.router.ts
index c15ce646c..9be861544 100644
--- a/apps/server/src/api-data/view-settings/viewSettings.router.ts
+++ b/apps/server/src/api-data/view-settings/viewSettings.router.ts
@@ -1,5 +1,5 @@
import express from 'express';
-import type { Request, Response } from 'express';
+import type { Request, Response, Router } from 'express';
import { type ErrorResponse, RefetchKey, type ViewSettings } from 'ontime-types';
import { getErrorMessage } from 'ontime-utils';
@@ -7,7 +7,7 @@ import { sendRefetch } from '../../adapters/WebsocketAdapter.js';
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';
import { validateViewSettings } from './viewSettings.validation.js';
-export const router = express.Router();
+export const router: Router = express.Router();
router.get('/', (_req: Request, res: Response) => {
const views = getDataProvider().getViewSettings();
diff --git a/apps/server/src/api-integration/integration.router.ts b/apps/server/src/api-integration/integration.router.ts
index 22857427e..b5543cd17 100644
--- a/apps/server/src/api-integration/integration.router.ts
+++ b/apps/server/src/api-integration/integration.router.ts
@@ -5,7 +5,7 @@
*
*/
-import express, { type Request, type Response } from 'express';
+import express, { Router, type Request, type Response } from 'express';
import { ErrorResponse, LogOrigin } from 'ontime-types';
import { getErrorMessage } from 'ontime-utils';
@@ -14,7 +14,7 @@ import { logger } from '../classes/Logger.js';
import { isEmptyObject } from '../utils/parserUtils.js';
import { dispatchFromAdapter } from './integration.controller.js';
-export const integrationRouter = express.Router();
+export const integrationRouter: Router = express.Router();
const helloMessage = 'You have reached Ontime API server';
diff --git a/apps/server/src/middleware/authenticate.ts b/apps/server/src/middleware/authenticate.ts
index 74b6f9ddf..3b28b23cd 100644
--- a/apps/server/src/middleware/authenticate.ts
+++ b/apps/server/src/middleware/authenticate.ts
@@ -1,7 +1,7 @@
import type { IncomingMessage } from 'node:http';
import { parse as parseCookie } from 'cookie';
-import express, { type NextFunction, type Request, type Response } from 'express';
+import express, { Router, type NextFunction, type Request, type Response } from 'express';
import type { WebSocket } from 'ws';
import { hasPassword, hashedPassword } from '../api-data/session/session.service.js';
@@ -40,7 +40,7 @@ export function isPublicAssetRequest(originalUrl: string, prefix: string): boole
* @param {string} prefix - Prefix is used for the client hashes in Ontime Cloud
*/
export function makeLoginRouter(prefix: string) {
- const router = express.Router();
+ const router: Router = express.Router();
// serve static files at root
router.use('/', express.static(srcFiles.login));