diff --git a/eslint.config.ts b/eslint.config.ts index 64d32de9..384962a0 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -18,8 +18,9 @@ export default [ ], }, eslint.configs.recommended, - ...tseslint.configs.recommended, - preferArrowFunctions.configs?.all ?? [], + ...tseslint.configs.strict, + ...tseslint.configs.stylistic, + preferArrowFunctions.configs.all, { languageOptions: { parserOptions: { @@ -100,6 +101,12 @@ export default [ "@typescript-eslint/no-misused-promises": "error", "@typescript-eslint/no-misused-new": "error", "@typescript-eslint/no-namespace": "error", + "@typescript-eslint/no-extraneous-class": "error", + "@typescript-eslint/no-invalid-void-type": "error", + "@typescript-eslint/consistent-type-definitions": [ + "error", + "type" + ], "@typescript-eslint/no-parameter-properties": "off", "@typescript-eslint/no-shadow": [ "error", diff --git a/package-lock.json b/package-lock.json index 7ec8560f..f1121812 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,7 +53,7 @@ "eslint": "^10.1.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-jsdoc": "^62.8.0", - "eslint-plugin-prefer-arrow-functions": "^3.9.1", + "eslint-plugin-prefer-arrow-functions": "^3.10.1", "globals": "^17.0.0", "jiti": "^2.6.1", "nodemon": "^3.0.2", @@ -5127,18 +5127,174 @@ } }, "node_modules/eslint-plugin-prefer-arrow-functions": { - "version": "3.9.1", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow-functions/-/eslint-plugin-prefer-arrow-functions-3.10.1.tgz", + "integrity": "sha512-wutwnNG0S/wqNhqryS7ee2yX01dkvgFMDvdaXcdEfSGcxz37FRfJUCD0YL2Jur0ANCKocgplF7n6GBPhe+DNNg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "^8.19.1", - "@typescript-eslint/utils": "^8.19.1" + "@typescript-eslint/types": "^8.62.1", + "@typescript-eslint/utils": "^8.62.1" }, "engines": { - "node": ">=18.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24.0.0" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-plugin-prefer-arrow-functions/node_modules/@typescript-eslint/project-service": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz", + "integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.65.0", + "@typescript-eslint/types": "^8.65.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/eslint-plugin-prefer-arrow-functions/node_modules/@typescript-eslint/scope-manager": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz", + "integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-prefer-arrow-functions/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz", + "integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/eslint-plugin-prefer-arrow-functions/node_modules/@typescript-eslint/types": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz", + "integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-prefer-arrow-functions/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz", + "integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.65.0", + "@typescript-eslint/tsconfig-utils": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": ">=9.17.0" + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/eslint-plugin-prefer-arrow-functions/node_modules/@typescript-eslint/utils": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz", + "integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/eslint-plugin-prefer-arrow-functions/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz", + "integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.65.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-prefer-arrow-functions/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/eslint-scope": { diff --git a/package.json b/package.json index 427441f5..c062518b 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "eslint": "^10.1.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-jsdoc": "^62.8.0", - "eslint-plugin-prefer-arrow-functions": "^3.9.1", + "eslint-plugin-prefer-arrow-functions": "^3.10.1", "globals": "^17.0.0", "jiti": "^2.6.1", "nodemon": "^3.0.2", diff --git a/src/app.ts b/src/app.ts index 809509a2..9f6a0d89 100644 --- a/src/app.ts +++ b/src/app.ts @@ -18,7 +18,7 @@ import { AnyDevice } from './device/device.js'; import WebSocketEvent from './device/webSocketEvent.js'; import AutomationEventType from './automation/automationEventType.js'; import LoggerServiceProvider from './serviceProvider/loggerServiceProvider.js'; -import DeviceDiscriminator from './serialization/discriminator/deviceDiscriminator.js'; +import deviceDiscriminator from './serialization/discriminator/deviceDiscriminator.js'; import ServiceMap from './serviceMap.js'; import SettingsEventType from './settings/settingsEventType.js'; import type Settings from './settings/settings.js'; @@ -34,19 +34,23 @@ import fs from 'fs' import BaseError from 'modern-errors'; import { Server } from 'socket.io'; -export type SslConfig = { port: number, keyFile: string, certFile: string }; +export type SslConfig = { + port: number; + keyFile: string; + certFile: string; +} -export interface AppOptions { +export type AppOptions = { allowedOrigins: string[]; dataPath: string; } -export interface ServeResult { +export type ServeResult = { httpServer: http.Server; httpsServer?: https.Server; } -export interface AppInstance { +export type AppInstance = { websocket: WebsocketServer; serve: (httpPort: number, sslConfig?: SslConfig) => ServeResult; shutdown: () => Promise; @@ -83,7 +87,7 @@ const configureWebsocket = (io: WebsocketServer, container: Container { - io.emit(WebSocketEvent.deviceConnected, serializer.transform(device, deviceDiscriminator)); + io.emit(WebSocketEvent.deviceConnected, serializer.transform(device, deviceDiscriminatorInstance)); void scriptRuntime.runForEvent({ type: DeviceManagerEvent.deviceConnected, device, args: [] }); }); deviceManager.on(DeviceManagerEvent.deviceDisconnected, (device: AnyDevice) => { - io.emit(WebSocketEvent.deviceDisconnected, serializer.transform(device, deviceDiscriminator)); + io.emit(WebSocketEvent.deviceDisconnected, serializer.transform(device, deviceDiscriminatorInstance)); void scriptRuntime.runForEvent({ type: DeviceManagerEvent.deviceDisconnected, device, args: [] }); }); deviceManager.on(DeviceManagerEvent.deviceRefreshed, (device: AnyDevice) => { - io.emit(WebSocketEvent.deviceRefreshed, serializer.transform(device, deviceDiscriminator)); + io.emit(WebSocketEvent.deviceRefreshed, serializer.transform(device, deviceDiscriminatorInstance)); void scriptRuntime.runForEvent({ type: DeviceManagerEvent.deviceRefreshed, device, args: [] }); }); deviceManager.on(DeviceManagerEvent.deviceNotification, (device: AnyDevice, notification) => { - io.emit(WebSocketEvent.deviceNotification, serializer.transform(device, deviceDiscriminator), notification); + io.emit(WebSocketEvent.deviceNotification, serializer.transform(device, deviceDiscriminatorInstance), notification); void scriptRuntime.runForEvent({ type: DeviceManagerEvent.deviceNotification, device, args: [notification] }); }); diff --git a/src/automation/scriptRuntime.ts b/src/automation/scriptRuntime.ts index 2dc01fcb..4aa5578f 100644 --- a/src/automation/scriptRuntime.ts +++ b/src/automation/scriptRuntime.ts @@ -13,9 +13,9 @@ export type SupportedDeviceEvent = | { type: DeviceManagerEvent.deviceNotification; device: AnyDevice; args: [notification: DeviceNotification] }; type ScriptRuntimeEvents = { - [AutomationEventType.consoleLog]: (data: string) => void, - [AutomationEventType.scriptStarted]: () => void, - [AutomationEventType.scriptStopped]: () => void, + [AutomationEventType.consoleLog]: (data: string) => void; + [AutomationEventType.scriptStarted]: () => void; + [AutomationEventType.scriptStopped]: () => void; } const AUTOMATION_LOG_FILENAME = 'automation.log'; @@ -156,7 +156,12 @@ export default class ScriptRuntime private async processQueue(): Promise { while (this.eventQueue.length > 0) { - const task = this.eventQueue.shift()!; + const task = this.eventQueue.shift(); + + if (undefined === task) { + continue; + } + try { await task(); } catch (e: unknown) { diff --git a/src/automation/scriptVm.ts b/src/automation/scriptVm.ts index 8f561546..b9c3ca5b 100644 --- a/src/automation/scriptVm.ts +++ b/src/automation/scriptVm.ts @@ -4,7 +4,7 @@ import { EventEmitter } from 'events'; export type ScriptVmSignalEvents = { eventDone: [errMsg: string | null]; lifecycleDone: [errMsg: string | null]; -}; +} export const LIFECYCLE_START = 'start'; export const LIFECYCLE_STOP = 'stop'; diff --git a/src/automation/scriptVmFactory.ts b/src/automation/scriptVmFactory.ts index 26d78818..ae3709b1 100644 --- a/src/automation/scriptVmFactory.ts +++ b/src/automation/scriptVmFactory.ts @@ -10,7 +10,7 @@ import ScriptVm, { LIFECYCLE_START, ScriptVmSignalEvents } from './scriptVm.js'; export type BridgeDevice = { id: string; name: string; -}; +} export const toBridgeDevice = (device: AnyDevice): BridgeDevice => { return { id: device.getDeviceId, name: device.getDeviceName }; diff --git a/src/controller/automation/createScriptController.ts b/src/controller/automation/createScriptController.ts index 6bace25c..6c6fa252 100644 --- a/src/controller/automation/createScriptController.ts +++ b/src/controller/automation/createScriptController.ts @@ -3,7 +3,10 @@ import ControllerInterface from '../controllerInterface.js'; import AutomationScriptRepositoryInterface from '../../repository/automationScriptRepositoryInterface.js'; import { isValidAutomationScriptFileName } from '../../automation/utils.js'; -type RequestParams = { fileName: string }; + +type RequestParams = { + fileName: string; +} type RequestBody = string; type CreateScriptRequest = Request; diff --git a/src/controller/automation/deleteScriptController.ts b/src/controller/automation/deleteScriptController.ts index 1808b597..ad7292f9 100644 --- a/src/controller/automation/deleteScriptController.ts +++ b/src/controller/automation/deleteScriptController.ts @@ -3,7 +3,8 @@ import ControllerInterface from '../controllerInterface.js'; import AutomationScriptRepositoryInterface from '../../repository/automationScriptRepositoryInterface.js'; import { isValidAutomationScriptFileName } from '../../automation/utils.js'; -type RequestParams = { fileName: string }; + +type RequestParams = { fileName: string } type DeleteScriptRequest = Request; export default class DeleteScriptController implements ControllerInterface diff --git a/src/controller/automation/getScriptController.ts b/src/controller/automation/getScriptController.ts index 9d728b62..dbce19c1 100644 --- a/src/controller/automation/getScriptController.ts +++ b/src/controller/automation/getScriptController.ts @@ -3,7 +3,10 @@ import ControllerInterface from '../controllerInterface.js'; import AutomationScriptRepositoryInterface from '../../repository/automationScriptRepositoryInterface.js'; import { isValidAutomationScriptFileName } from '../../automation/utils.js'; -type RequestParams = { fileName: string }; +type RequestParams = { + fileName: string; +} + type GetScriptRequest = Request; export default class GetScriptController implements ControllerInterface diff --git a/src/controller/controllerInterface.ts b/src/controller/controllerInterface.ts index 316964ba..11be4e89 100644 --- a/src/controller/controllerInterface.ts +++ b/src/controller/controllerInterface.ts @@ -1,6 +1,6 @@ import { Request, Response } from 'express'; -export default interface ControllerInterface -{ +type ControllerInterface = { execute(req: Request, res: Response): void | Promise; } +export default ControllerInterface diff --git a/src/controller/getDeviceController.ts b/src/controller/getDeviceController.ts index b6b3ecb8..e563d57f 100644 --- a/src/controller/getDeviceController.ts +++ b/src/controller/getDeviceController.ts @@ -2,7 +2,7 @@ import { Request, Response } from 'express'; import ControllerInterface from './controllerInterface.js'; import ClassToPlainSerializer from '../serialization/classToPlainSerializer.js'; import ConnectedDeviceRepository from '../repository/connectedDeviceRepository.js'; -import DeviceDiscriminator from '../serialization/discriminator/deviceDiscriminator.js'; +import deviceDiscriminator from '../serialization/discriminator/deviceDiscriminator.js'; import { DeviceId } from '../device/deviceId.js'; type GetDeviceRequest = Request<{ deviceId: DeviceId }>; @@ -31,7 +31,7 @@ export default class GetDeviceController implements ControllerInterface res.json(this.serializer.transform( device, - DeviceDiscriminator.createClassTransformerTypeDiscriminator('type') + deviceDiscriminator.createClassTransformerTypeDiscriminator('type') )); } } diff --git a/src/device/attribute/listDeviceAttribute.ts b/src/device/attribute/listDeviceAttribute.ts index 63747578..afdd8edb 100644 --- a/src/device/attribute/listDeviceAttribute.ts +++ b/src/device/attribute/listDeviceAttribute.ts @@ -8,7 +8,7 @@ export type InitializedListDeviceAttribute< IValue extends ListDeviceAttributeItem > = ListDeviceAttribute; -export type ListDeviceAttributeOption = { key: IKey, value: IValue }; +export type ListDeviceAttributeOption = { key: IKey, value: IValue } export type ListDeviceAttributeOptions = ListDeviceAttributeOption[]; export default class ListDeviceAttribute< diff --git a/src/device/bleDevice.ts b/src/device/bleDevice.ts index 84ebfc18..41e7df82 100644 --- a/src/device/bleDevice.ts +++ b/src/device/bleDevice.ts @@ -21,7 +21,7 @@ export default abstract class BleDevice< private readonly rssiInterval: NodeJS.Timeout; private readonly reconnectHandler: () => void; - private closing: boolean = false; + private closing = false; @Expose() private rssi: number; diff --git a/src/device/detectedDeviceOfferQueue.ts b/src/device/detectedDeviceOfferQueue.ts index 9f73eb30..13677ef7 100644 --- a/src/device/detectedDeviceOfferQueue.ts +++ b/src/device/detectedDeviceOfferQueue.ts @@ -14,7 +14,7 @@ type DeviceOffer = (cancellationToken: CancellationToken) = export default class DetectedDeviceOfferQueue { - private readonly queues: Map = new Map(); + private readonly queues = new Map(); private readonly logger: Logger; diff --git a/src/device/deviceManager.ts b/src/device/deviceManager.ts index ffeab52c..9c1f4e03 100644 --- a/src/device/deviceManager.ts +++ b/src/device/deviceManager.ts @@ -13,7 +13,7 @@ import DetectedDeviceOfferQueue, { OfferResult } from './detectedDeviceOfferQueu export type DeviceDetectionInfo = { type: string; detectionId: DetectionId; -}; +} export enum DeviceManagerEvent { deviceConnected = 'deviceConnected', @@ -27,7 +27,7 @@ type DisabledDetectedDevice = { deviceDetectionInfo: DeviceDetectionInfo; canonicalId: DeviceId; deviceReleased: Promise; -}; +} type DeviceManagerEventMap = { [DeviceManagerEvent.deviceConnected]: [device: AnyDevice]; @@ -37,7 +37,7 @@ type DeviceManagerEventMap = { [DeviceManagerEvent.deviceNotification]: [device: AnyDevice, notification: DeviceNotification]; } -type ConnectedDevice = { device: AnyDevice, deviceDetectionInfo: DeviceDetectionInfo }; +type ConnectedDevice = { device: AnyDevice, deviceDetectionInfo: DeviceDetectionInfo } export default class DeviceManager { @@ -49,9 +49,9 @@ export default class DeviceManager private readonly settingsManager: SettingsManager; - private readonly detectedDisabledDevices: Map = new Map(); + private readonly detectedDisabledDevices = new Map(); - private readonly connectedDevices: Map = new Map(); + private readonly connectedDevices = new Map(); // Serializes onSettingsChanged() runs so rapid settings changes don't interleave private readonly settingsChangeQueue: SequentialTaskQueue = new SequentialTaskQueue(); diff --git a/src/device/genericDeviceUpdater.ts b/src/device/genericDeviceUpdater.ts index e8acec94..9a11c995 100644 --- a/src/device/genericDeviceUpdater.ts +++ b/src/device/genericDeviceUpdater.ts @@ -9,7 +9,7 @@ export default class GenericDeviceUpdater extends AbstractDeviceUpdater { private logger: Logger; - private readonly failedMessageCountPerDevice: Map = new Map(); + private readonly failedMessageCountPerDevice = new Map(); public constructor(serializer: PlainToClassSerializer, logger: Logger) { super(serializer); diff --git a/src/device/protocol/airotic/airoticDevice.ts b/src/device/protocol/airotic/airoticDevice.ts index 7c182935..23bb445f 100644 --- a/src/device/protocol/airotic/airoticDevice.ts +++ b/src/device/protocol/airotic/airoticDevice.ts @@ -25,20 +25,22 @@ const DEFAULT_BREATH_IN_COLOR = '255,0,128'; export type BpmTrend = 'up' | 'down' | 'stable'; + export type AiroticDeviceAttributes = { - restColor: StrDeviceAttribute, - breathInColor: StrDeviceAttribute, - resetColors: BoolDeviceAttribute, - reboot: BoolDeviceAttribute, - breathsPerMin: FloatDeviceAttribute, - bpmTrend: StrDeviceAttribute, + restColor: StrDeviceAttribute; + breathInColor: StrDeviceAttribute; + resetColors: BoolDeviceAttribute; + reboot: BoolDeviceAttribute; + breathsPerMin: FloatDeviceAttribute; + bpmTrend: StrDeviceAttribute; }; + export type AiroticDeviceNotifications = { colorChange: { colorType: 'breathInColor' | 'restColor'; }; -}; +} @Exclude() export default class AiroticDevice extends BleDevice diff --git a/src/device/protocol/deviceProtocol.ts b/src/device/protocol/deviceProtocol.ts index 2dcad029..bd1daa11 100644 --- a/src/device/protocol/deviceProtocol.ts +++ b/src/device/protocol/deviceProtocol.ts @@ -21,14 +21,14 @@ export type InferMR

= P extends DeviceProtocol> export type InferMessage = MR extends MessageWithResponse ? M : MR extends Message ? M : never; export type InferResponse = MR extends MessageWithResponse ? R : - MR extends Message ? void : never; + MR extends Message ? undefined : never; -export default interface DeviceProtocol> -{ +type DeviceProtocol> = { encode(message: InferMessage): Buffer; decode(data: Buffer): DecodeResult>; isResponseMatchingMessage(response: InferResponse, message: MR): boolean; } +export default DeviceProtocol export const getErrorFromDecodeResult = (protocolError: ProtocolError, transportResponse: Buffer): Error => { switch (protocolError.type) { diff --git a/src/device/protocol/estim2b/estim2bDevice.ts b/src/device/protocol/estim2b/estim2bDevice.ts index e089085f..f12af370 100644 --- a/src/device/protocol/estim2b/estim2bDevice.ts +++ b/src/device/protocol/estim2b/estim2bDevice.ts @@ -14,6 +14,7 @@ import EventEmitter from 'events'; import Logger from '../../../logging/Logger.js'; import { DeviceId } from '../../deviceId.js'; + export type EStim2bDeviceAttributes = { mode: ListDeviceAttribute, channelALevel: IntRangeDeviceAttribute, diff --git a/src/device/protocol/estim2b/estim2bProtocol.ts b/src/device/protocol/estim2b/estim2bProtocol.ts index 58147afe..acc2e00b 100644 --- a/src/device/protocol/estim2b/estim2bProtocol.ts +++ b/src/device/protocol/estim2b/estim2bProtocol.ts @@ -10,7 +10,7 @@ export type EStim2bStatus = { powerMode: string, channelsJoined: boolean, firmwareVersion: string, -}; +} export type EStim2Channel = 'A' | 'B'; export type EStim2PowerMode = 'H' | 'L'; diff --git a/src/device/protocol/messageResponseHandler.ts b/src/device/protocol/messageResponseHandler.ts index 598acbc1..e22c9ea6 100644 --- a/src/device/protocol/messageResponseHandler.ts +++ b/src/device/protocol/messageResponseHandler.ts @@ -11,21 +11,21 @@ type PendingEntry = { timeout: ReturnType; timeoutMs: number, pendingSince: number, -}; +} export default class MessageResponseHandler

>> { private readonly protocol: P; private readonly transport: DeviceBidirectionalTransport; private readonly logger: Logger; - private readonly pendingEntries: Set>> = new Set(); + private readonly pendingEntries = new Set>>(); private readonly timeoutMs: number; public static create

>>( protocol: P, transport: DeviceBidirectionalTransport, logger: Logger, - timeoutMs: number = 200, + timeoutMs = 200, ): MessageResponseHandler

{ return new this(protocol, transport, logger, timeoutMs); } diff --git a/src/device/protocol/slvCtrlPlus/slvCtrlProtocol.ts b/src/device/protocol/slvCtrlPlus/slvCtrlProtocol.ts index e6dc35f7..69b68b2e 100644 --- a/src/device/protocol/slvCtrlPlus/slvCtrlProtocol.ts +++ b/src/device/protocol/slvCtrlPlus/slvCtrlProtocol.ts @@ -5,18 +5,16 @@ export type DeviceInfo = { deviceType: string, fwVersion: number, protocolVersion: number, -}; -export type KeyValuePairs = { [key: string]: string }; +} +export type KeyValuePairs = Record; export type Result = { status: 'ok' | 'error' | 'unknown', reason?: string, -} & { - [key: string]: string, -} +} & Record export type SlvCtrlProtocolCommand = { command: string; args: (string|number|boolean)[]; -}; +} export type SlvCtrlProtocolResponse = { command: string, data: KeyValuePairs, diff --git a/src/device/protocol/slvCtrlPlus/slvCtrlProtocolLegacy.ts b/src/device/protocol/slvCtrlPlus/slvCtrlProtocolLegacy.ts index a2c718a9..734f70a3 100644 --- a/src/device/protocol/slvCtrlPlus/slvCtrlProtocolLegacy.ts +++ b/src/device/protocol/slvCtrlPlus/slvCtrlProtocolLegacy.ts @@ -17,9 +17,9 @@ type SetAttributeResponse = { command: string, value: string, status: string, -}; +} -export type StatusResponse = { [key: string]: string }; +export type StatusResponse = Record; export default class SlvCtrlProtocolLegacy extends SlvCtrlProtocol { diff --git a/src/device/protocol/virtual/audio/piperVirtualDeviceLogic.ts b/src/device/protocol/virtual/audio/piperVirtualDeviceLogic.ts index fb74ba84..5a4a9ac9 100644 --- a/src/device/protocol/virtual/audio/piperVirtualDeviceLogic.ts +++ b/src/device/protocol/virtual/audio/piperVirtualDeviceLogic.ts @@ -40,7 +40,7 @@ export default class PiperVirtualDeviceLogic extends VirtualDeviceLogic< private piperProcess?: ChildProcessByStdio; private speaker?: Speaker; private speakerOptions: Speaker.Options = {}; - private speakerCoolDown: boolean = false; + private speakerCoolDown = false; public constructor(config: PiperVirtualDeviceConfig, logger: Logger) { super(config); @@ -72,7 +72,7 @@ export default class PiperVirtualDeviceLogic extends VirtualDeviceLogic< // If queuing is disabled, we must destroy speaker to end output // and return because we need to wait until the stdout of piper // process is drained (see stopPlayback() for details) - if (!queuing && this.stopPlayback()) { + if (false === queuing && this.stopPlayback()) { return; } @@ -107,9 +107,7 @@ export default class PiperVirtualDeviceLogic extends VirtualDeviceLogic< }; } - public get refreshInterval(): number { - return 175; - } + public readonly refreshInterval = 175; private async startPiper(): Promise { if (undefined !== this.piperProcess) { diff --git a/src/device/protocol/virtual/audio/ttsVirtualDeviceLogic.ts b/src/device/protocol/virtual/audio/ttsVirtualDeviceLogic.ts index f2a7c170..dd85ae08 100644 --- a/src/device/protocol/virtual/audio/ttsVirtualDeviceLogic.ts +++ b/src/device/protocol/virtual/audio/ttsVirtualDeviceLogic.ts @@ -9,6 +9,7 @@ import { Int } from '../../../../util/numbers.js'; import Logger from '../../../../logging/Logger.js'; import { TtsVirtualDeviceConfig } from './ttsVirtualDeviceConfig.js'; + type TtsVirtualDeviceAttributes = { text: StrDeviceAttribute; speaking: BoolDeviceAttribute; @@ -79,9 +80,7 @@ export default class TtsVirtualDeviceLogic extends VirtualDeviceLogic< await device.setAttribute('queueLength', Int.from(this.ttsEntries.length)); } - public get refreshInterval(): number { - return 175; - } + public readonly refreshInterval = 175; public configureAttributes(): TtsVirtualDeviceAttributes { const textAttr = StrDeviceAttribute.create( diff --git a/src/device/protocol/virtual/display/displayVirtualDeviceLogic.ts b/src/device/protocol/virtual/display/displayVirtualDeviceLogic.ts index 8b5de8be..5af8d837 100644 --- a/src/device/protocol/virtual/display/displayVirtualDeviceLogic.ts +++ b/src/device/protocol/virtual/display/displayVirtualDeviceLogic.ts @@ -17,9 +17,7 @@ export default class DisplayVirtualDeviceLogic extends VirtualDeviceLogic, TConfigS : never : never ), -}; +} export default class GenericVirtualDeviceFactory implements VirtualDeviceFactory { private readonly dateFactory: DateFactory; @@ -29,7 +29,7 @@ export default class GenericVirtualDeviceFactory implements VirtualDeviceFactory private readonly jsonSchemaValidatorFactory: JsonSchemaValidatorFactory; - private readonly logicFactories: Map, TObject>> = new Map(); + private readonly logicFactories = new Map, TObject>>(); private readonly logger: Logger; diff --git a/src/device/protocol/virtual/randomGenerator/randomGeneratorVirtualDeviceLogic.ts b/src/device/protocol/virtual/randomGenerator/randomGeneratorVirtualDeviceLogic.ts index 55578cf0..a5d05972 100644 --- a/src/device/protocol/virtual/randomGenerator/randomGeneratorVirtualDeviceLogic.ts +++ b/src/device/protocol/virtual/randomGenerator/randomGeneratorVirtualDeviceLogic.ts @@ -5,6 +5,7 @@ import VirtualDevice from '../virtualDevice.js'; import { Int } from '../../../../util/numbers.js'; import { RandomGeneratorVirtualDeviceConfig } from './randomGeneratorVirtualDeviceConfig.js'; + type RandomGeneratorVirtualDeviceAttributes = { value: IntDeviceAttribute; } @@ -23,9 +24,7 @@ export default class RandomGeneratorVirtualDeviceLogic extends VirtualDeviceLogi } } - public get refreshInterval(): number { - return 100; - } + public readonly refreshInterval = 100; public async refreshData(device: VirtualDevice): Promise { const currentNumber = (await device.getAttribute('value'))?.value; diff --git a/src/device/protocol/virtual/virtualDeviceFactory.ts b/src/device/protocol/virtual/virtualDeviceFactory.ts index fb665eb5..ab71af77 100644 --- a/src/device/protocol/virtual/virtualDeviceFactory.ts +++ b/src/device/protocol/virtual/virtualDeviceFactory.ts @@ -1,6 +1,7 @@ import KnownDevice from '../../../settings/knownDevice.js'; import VirtualDevice from './virtualDevice.js'; -export default interface VirtualDeviceFactory { +type VirtualDeviceFactory = { create(knownDevice: KnownDevice, provider: string): Promise>; } +export default VirtualDeviceFactory diff --git a/src/device/protocol/virtual/virtualDeviceLogicFactory.ts b/src/device/protocol/virtual/virtualDeviceLogicFactory.ts index 1b002d31..937728f6 100644 --- a/src/device/protocol/virtual/virtualDeviceLogicFactory.ts +++ b/src/device/protocol/virtual/virtualDeviceLogicFactory.ts @@ -2,9 +2,9 @@ import VirtualDeviceLogic from './virtualDeviceLogic.js'; type ExtractConfig> = T extends VirtualDeviceLogic ? C : never; -export default interface VirtualDeviceLogicFactory> -{ +type VirtualDeviceLogicFactory> = { create(config: ExtractConfig): TDeviceLogic; forDeviceType(): string; } +export default VirtualDeviceLogicFactory diff --git a/src/device/protocol/zc95/zc95Device.ts b/src/device/protocol/zc95/zc95Device.ts index 5124722c..6336d9a0 100644 --- a/src/device/protocol/zc95/zc95Device.ts +++ b/src/device/protocol/zc95/zc95Device.ts @@ -28,21 +28,17 @@ import { DeviceId } from '../../deviceId.js'; type RequiredZc95DeviceAttributes = { activePattern: InitializedListDeviceAttribute; patternStarted: InitializedBoolDeviceAttribute; -}; +} type Zc95DevicePowerChannelAttributesKeyPrefix = `powerChannel`; type Zc95DevicePowerChannelAttributesKey = `${Zc95DevicePowerChannelAttributesKeyPrefix}${1 | 2 | 3 | 4}`; -type Zc95DevicePowerChannelAttributes = { - [K in Zc95DevicePowerChannelAttributesKey]: IntRangeDeviceAttribute; -} +type Zc95DevicePowerChannelAttributes = Record type Zc95DevicePatternAttributesKeyPrefix = `patternAttribute`; type Zc95DevicePatternAttributesKey = `${Zc95DevicePatternAttributesKeyPrefix}${number}`; -type Zc95DevicePatternAttributes = { - [key in Zc95DevicePatternAttributesKey]: InitializedIntRangeDeviceAttribute | ListDeviceAttribute; -} +type Zc95DevicePatternAttributes = Record> export type Zc95DeviceAttributes = Partial & Zc95DevicePatternAttributes> & Required; @@ -258,7 +254,7 @@ export default class Zc95Device extends PeripheralDevice { const msgId = this.getNextMsgIndex(); diff --git a/src/device/protocol/zc95/zc95Protocol.ts b/src/device/protocol/zc95/zc95Protocol.ts index 768dec34..3b1865be 100644 --- a/src/device/protocol/zc95/zc95Protocol.ts +++ b/src/device/protocol/zc95/zc95Protocol.ts @@ -3,29 +3,26 @@ import BaseError from 'modern-errors'; type ResponseToKey = R extends { Type: infer T } ? T : never; -export interface Msg -{ +export type Msg = { Type: string; MsgId: number; } -export interface MsgResponse -{ +export type MsgResponse = { Type: string; MsgId: number; Result: 'OK' | 'ERROR' Error?: string; } -export interface ResponseIdentifier -{ +export type ResponseIdentifier = { msgId: number, type: ResponseToKey } -export interface MsgAndResponseIdentifier extends MessageWithResponse { +export type MsgAndResponseIdentifier = { responseIdentifier: ResponseIdentifier; -} +} & MessageWithResponse export type Zc95ProtocolMessage = MsgAndResponseIdentifier; diff --git a/src/device/protocol/zc95/zc95SerialDeviceProvider.ts b/src/device/protocol/zc95/zc95SerialDeviceProvider.ts index f340a403..e290feaa 100644 --- a/src/device/protocol/zc95/zc95SerialDeviceProvider.ts +++ b/src/device/protocol/zc95/zc95SerialDeviceProvider.ts @@ -76,7 +76,7 @@ export default class Zc95SerialDeviceProvider extends SerialDeviceProvider, close: boolean = false): Promise { + private async reset(port: SerialPortStream, close = false): Promise { return new Promise((resolve, reject) => { port.write(Buffer.from([Zc95Protocol.EOT]), (writeErr: Error | null | undefined) => { if (null != writeErr) { diff --git a/src/device/provider/deviceProvider.ts b/src/device/provider/deviceProvider.ts index 94bb51b1..dfed7c65 100644 --- a/src/device/provider/deviceProvider.ts +++ b/src/device/provider/deviceProvider.ts @@ -15,11 +15,11 @@ export default abstract class DeviceProvider = new Map(); + private readonly connectedDevices = new Map(); private readonly deviceDetectedListener: (deviceDetectionInfo: DeviceDetectionInfo) => void; - private running: boolean = false; + private running = false; protected constructor(deviceManager: DeviceManager, logger: Logger) { this.deviceManager = deviceManager; diff --git a/src/device/provider/deviceProviderFactory.ts b/src/device/provider/deviceProviderFactory.ts index a6e38cd0..27808bef 100644 --- a/src/device/provider/deviceProviderFactory.ts +++ b/src/device/provider/deviceProviderFactory.ts @@ -1,7 +1,7 @@ import { AnyDeviceProvider } from './deviceProvider.js'; import { JsonObject } from '../../types.js'; -export default interface DeviceProviderFactory -{ +type DeviceProviderFactory = { create(config: JsonObject): DP; } +export default DeviceProviderFactory diff --git a/src/device/provider/deviceProviderManager.ts b/src/device/provider/deviceProviderManager.ts index 0bd91979..999ee71f 100644 --- a/src/device/provider/deviceProviderManager.ts +++ b/src/device/provider/deviceProviderManager.ts @@ -9,7 +9,7 @@ import { logError } from '../../util/error.js'; type RunningProvider = { provider: AnyDeviceProvider; sourceFingerprint: string; -}; +} export default class DeviceProviderManager { @@ -17,7 +17,7 @@ export default class DeviceProviderManager private readonly logger: Logger; - private readonly providers: Map = new Map(); + private readonly providers = new Map(); // Settings can change in rapid succession, so overlapping loadFromSettings()/stopProviders() // calls are serialized to avoid racing on the shared providers map diff --git a/src/device/transport/bleDeviceTransport.ts b/src/device/transport/bleDeviceTransport.ts index 042c8923..3aee9634 100644 --- a/src/device/transport/bleDeviceTransport.ts +++ b/src/device/transport/bleDeviceTransport.ts @@ -11,8 +11,8 @@ export default class BleUartDeviceTransport implements DeviceBidirectionalTransp private readonly uartRxCharacteristicUuid: string; private readonly uartTxCharacteristicUuid: string; - private isConnected: boolean = false; - private isSubscribing: boolean = false; + private isConnected = false; + private isSubscribing = false; private onCloseSubscribers: (() => Promise)[] = []; private onReceiveSubscribers: ((data: Buffer) => void)[] = []; diff --git a/src/device/transport/deviceBidirectionalTransport.ts b/src/device/transport/deviceBidirectionalTransport.ts index 585473d6..6ae36724 100644 --- a/src/device/transport/deviceBidirectionalTransport.ts +++ b/src/device/transport/deviceBidirectionalTransport.ts @@ -1,12 +1,12 @@ import DeviceReadableTransport from './deviceReadableTransport.js'; import DeviceWritableTransport from './deviceWritableTransport.js'; -export default interface DeviceTransport extends DeviceReadableTransport, DeviceWritableTransport -{ +type DeviceTransport = { /** * Writes data and waits for a response associated to it and returns it as a result * @param data The command/input for the device * @param timeout The timeout the transport should wait for the operation to complete and get a response */ sendAndAwaitReceive(data: Buffer, timeout?: number): Promise; -} +} & DeviceReadableTransport & DeviceWritableTransport +export default DeviceTransport diff --git a/src/device/transport/deviceReadableTransport.ts b/src/device/transport/deviceReadableTransport.ts index 2b8e21f5..afe2c0ed 100644 --- a/src/device/transport/deviceReadableTransport.ts +++ b/src/device/transport/deviceReadableTransport.ts @@ -1,5 +1,4 @@ -export default interface DeviceReadableTransport -{ +type DeviceReadableTransport = { /** * When data is received * @param dataProcessor @@ -27,3 +26,4 @@ export default interface DeviceReadableTransport */ getDeviceIdentifier(): string; } +export default DeviceReadableTransport diff --git a/src/device/transport/deviceWritableTransport.ts b/src/device/transport/deviceWritableTransport.ts index 55563af9..abfc8157 100644 --- a/src/device/transport/deviceWritableTransport.ts +++ b/src/device/transport/deviceWritableTransport.ts @@ -1,5 +1,4 @@ -export default interface DeviceWritableTransport -{ +type DeviceWritableTransport = { /** * Writes data * @param data The command/input for the device @@ -27,3 +26,4 @@ export default interface DeviceWritableTransport */ getDeviceIdentifier(): string; } +export default DeviceWritableTransport diff --git a/src/device/transport/serialPortObserver.ts b/src/device/transport/serialPortObserver.ts index 61aac3f9..4e74d777 100644 --- a/src/device/transport/serialPortObserver.ts +++ b/src/device/transport/serialPortObserver.ts @@ -18,13 +18,13 @@ export default class SerialPortObserver extends SharedObserver { protected readonly deviceManager: DeviceManager; - private managedDevices: Map = new Map(); + private managedDevices = new Map(); private onUsbEventRef?: () => void; private rescanTimer?: NodeJS.Timeout; - private readonly discoveryQueue: LatestOnlyTaskQueue = new LatestOnlyTaskQueue(); + private readonly discoveryQueue = new LatestOnlyTaskQueue(); public constructor( deviceManager: DeviceManager, @@ -78,7 +78,7 @@ export default class SerialPortObserver extends SharedObserver public async discoverSerialDevices(cancellationToken?: CancellationToken): Promise { - const foundDevices: Map = new Map(); + const foundDevices = new Map(); let ports: PortInfo[]; try { diff --git a/src/device/updater/bufferedDeviceUpdater.ts b/src/device/updater/bufferedDeviceUpdater.ts index b58b97bf..3ce936e7 100644 --- a/src/device/updater/bufferedDeviceUpdater.ts +++ b/src/device/updater/bufferedDeviceUpdater.ts @@ -8,6 +8,14 @@ export default class BufferedDeviceUpdater implements DeviceUpdaterInterface private readonly queue: SequentialTaskQueue; + private static readonly handleUpdate = async ( + deviceUpdater: DeviceUpdaterInterface, + device: AnyDevice, + deviceData: DeviceData + ): Promise => { + await deviceUpdater.update(device, deviceData); + }; + public constructor(decoratedDeviceUpdater: DeviceUpdaterInterface) { this.decoratedDeviceUpdater = decoratedDeviceUpdater; this.queue = new SequentialTaskQueue(); @@ -16,13 +24,4 @@ export default class BufferedDeviceUpdater implements DeviceUpdaterInterface public async update(device: AnyDevice, deviceData: DeviceData): Promise { await this.queue.push(BufferedDeviceUpdater.handleUpdate, { args: [this.decoratedDeviceUpdater, device, deviceData] }); } - - private static async handleUpdate( - this: void, - deviceUpdater: DeviceUpdaterInterface, - device: AnyDevice, - deviceData: DeviceData - ): Promise { - await deviceUpdater.update(device, deviceData); - } } diff --git a/src/device/updater/deviceUpdaterInterface.ts b/src/device/updater/deviceUpdaterInterface.ts index 60f14596..4719f482 100644 --- a/src/device/updater/deviceUpdaterInterface.ts +++ b/src/device/updater/deviceUpdaterInterface.ts @@ -1,6 +1,6 @@ import { AnyDevice, DeviceData } from '../device.js'; -export default interface DeviceUpdaterInterface -{ +type DeviceUpdaterInterface = { update(device: AnyDevice, rawData: DeviceData): Promise; } +export default DeviceUpdaterInterface diff --git a/src/entity/deviceList.ts b/src/entity/deviceList.ts index 34a345bc..3081cb4e 100644 --- a/src/entity/deviceList.ts +++ b/src/entity/deviceList.ts @@ -1,11 +1,11 @@ import { Exclude, Type } from 'class-transformer'; import Device, { AnyDevice } from '../device/device.js'; import List from './list.js'; -import DeviceDiscriminator from '../serialization/discriminator/deviceDiscriminator.js'; +import deviceDiscriminator from '../serialization/discriminator/deviceDiscriminator.js'; @Exclude() export default class DeviceList extends List { - @Type(() => Device, DeviceDiscriminator.createClassTransformerTypeDiscriminator('type')) + @Type(() => Device, deviceDiscriminator.createClassTransformerTypeDiscriminator('type')) protected readonly declare items: AnyDevice[]; } diff --git a/src/health/serializedTypes.ts b/src/health/serializedTypes.ts index 45f3ed35..fe8628b8 100644 --- a/src/health/serializedTypes.ts +++ b/src/health/serializedTypes.ts @@ -31,4 +31,4 @@ export type SerializedHealthMetrics = { hostname: string | null, uptime: number | null, }, -}; +} diff --git a/src/logging/Logger.ts b/src/logging/Logger.ts index ba529dce..498aa313 100644 --- a/src/logging/Logger.ts +++ b/src/logging/Logger.ts @@ -6,10 +6,9 @@ export type ChildLoggerOptions = { level?: string, } -export type ErrorContext = Error | ({ error: Error } & { [key: string]: unknown }); +export type ErrorContext = Error | ({ error: Error } & Record); -export default interface Logger -{ +type Logger = { child(bindings?: ChildLoggerBindings, options?: ChildLoggerOptions): Logger; trace(msg: string, context?: unknown): void; @@ -19,3 +18,4 @@ export default interface Logger error(msg: string, context?: ErrorContext | unknown): void; fatal(msg: string, context?: unknown): void; } +export default Logger diff --git a/src/repository/automationScriptRepositoryInterface.ts b/src/repository/automationScriptRepositoryInterface.ts index 6f5343c4..a2305250 100644 --- a/src/repository/automationScriptRepositoryInterface.ts +++ b/src/repository/automationScriptRepositoryInterface.ts @@ -1,7 +1,6 @@ import AutomationScript from '../entity/automationScript.js'; -export default interface AutomationScriptRepositoryInterface -{ +type AutomationScriptRepositoryInterface = { getAll(): AutomationScript[]; getByName(name: string): string|null; @@ -10,3 +9,4 @@ export default interface AutomationScriptRepositoryInterface delete(fileName: string): void; } +export default AutomationScriptRepositoryInterface diff --git a/src/repository/deviceRepositoryInterface.ts b/src/repository/deviceRepositoryInterface.ts index d0cc3aa0..b30a36d4 100644 --- a/src/repository/deviceRepositoryInterface.ts +++ b/src/repository/deviceRepositoryInterface.ts @@ -1,8 +1,8 @@ import { AnyDevice } from '../device/device.js'; -export default interface DeviceRepositoryInterface -{ +type DeviceRepositoryInterface = { getAll(): AnyDevice[]; getById(uuid: string): AnyDevice|null; } +export default DeviceRepositoryInterface diff --git a/src/serial/frameParser.ts b/src/serial/frameParser.ts index f1a73bc5..05d168ff 100644 --- a/src/serial/frameParser.ts +++ b/src/serial/frameParser.ts @@ -1,11 +1,10 @@ import { Transform, TransformCallback, TransformOptions } from 'stream'; -export interface FrameParserOptions extends TransformOptions -{ +export type FrameParserOptions = { stx: number; etx: number; maxMessageSize?: number; -} +} & TransformOptions type State = 'IDLE' | 'RECV'; diff --git a/src/serialization/discriminator/deviceDiscriminator.ts b/src/serialization/discriminator/deviceDiscriminator.ts index 772ae685..4fd70c8b 100644 --- a/src/serialization/discriminator/deviceDiscriminator.ts +++ b/src/serialization/discriminator/deviceDiscriminator.ts @@ -6,14 +6,13 @@ import Zc95Device from '../../device/protocol/zc95/zc95Device.js'; import EStim2bDevice from '../../device/protocol/estim2b/estim2bDevice.js'; import AiroticDevice from '../../device/protocol/airotic/airoticDevice.js'; -export default class DeviceDiscriminator extends ObjectDiscriminator -{ - protected static override discriminatorMap = [ - { value: GenericSlvCtrlPlusDevice, name: 'slvCtrlPlus' }, - { value: ButtplugIoDevice, name: 'buttplugIo' }, - { value: Zc95Device, name: 'zc95' }, - { value: VirtualDevice, name: 'virtual' }, - { value: EStim2bDevice, name: 'estim2b' }, - { value: AiroticDevice, name: 'airotic' }, - ]; -} +const deviceDiscriminator = new ObjectDiscriminator([ + { value: GenericSlvCtrlPlusDevice, name: 'slvCtrlPlus' }, + { value: ButtplugIoDevice, name: 'buttplugIo' }, + { value: Zc95Device, name: 'zc95' }, + { value: VirtualDevice, name: 'virtual' }, + { value: EStim2bDevice, name: 'estim2b' }, + { value: AiroticDevice, name: 'airotic' }, +]); + +export default deviceDiscriminator; diff --git a/src/serialization/discriminator/genericDeviceAttributeDiscriminator.ts b/src/serialization/discriminator/genericDeviceAttributeDiscriminator.ts index b0c42deb..1255e415 100644 --- a/src/serialization/discriminator/genericDeviceAttributeDiscriminator.ts +++ b/src/serialization/discriminator/genericDeviceAttributeDiscriminator.ts @@ -6,13 +6,13 @@ import StrDeviceAttribute from '../../device/attribute/strDeviceAttribute.js'; import IntRangeDeviceAttribute from '../../device/attribute/intRangeDeviceAttribute.js'; import ListDeviceAttribute from '../../device/attribute/listDeviceAttribute.js'; -export default class GenericDeviceAttributeDiscriminator extends ObjectDiscriminator { - protected static override discriminatorMap = [ - { value: BoolDeviceAttribute, name: 'bool' }, - { value: IntDeviceAttribute, name: 'int' }, - { value: FloatDeviceAttribute, name: 'float' }, - { value: StrDeviceAttribute, name: 'str' }, - { value: IntRangeDeviceAttribute, name: 'range' }, - { value: ListDeviceAttribute, name: 'list' } - ]; -} +const genericDeviceAttributeDiscriminator = new ObjectDiscriminator([ + { value: BoolDeviceAttribute, name: 'bool' }, + { value: IntDeviceAttribute, name: 'int' }, + { value: FloatDeviceAttribute, name: 'float' }, + { value: StrDeviceAttribute, name: 'str' }, + { value: IntRangeDeviceAttribute, name: 'range' }, + { value: ListDeviceAttribute, name: 'list' } +]); + +export default genericDeviceAttributeDiscriminator; diff --git a/src/serialization/discriminator/objectDiscriminator.ts b/src/serialization/discriminator/objectDiscriminator.ts index f81918af..83db43ef 100644 --- a/src/serialization/discriminator/objectDiscriminator.ts +++ b/src/serialization/discriminator/objectDiscriminator.ts @@ -1,20 +1,20 @@ import { ClassConstructor, TypeOptions } from 'class-transformer'; type DiscriminatorMap = { - /** - * Name of the type. - */ + // Name of the type. name: string; - /** - * A class constructor which can be used to create the object. - */ + // A class constructor which can be used to create the object. value: ClassConstructor; }[]; -export default abstract class ObjectDiscriminator { - protected static discriminatorMap: DiscriminatorMap; +export default class ObjectDiscriminator { + private readonly discriminatorMap: DiscriminatorMap; - public static fromName(name: string): ClassConstructor { + public constructor(discriminatorMap: DiscriminatorMap) { + this.discriminatorMap = discriminatorMap; + } + + public fromName(name: string): ClassConstructor { for (const subType of this.discriminatorMap) { if (subType.name === name) { return subType.value; @@ -24,7 +24,7 @@ export default abstract class ObjectDiscriminator { throw new Error(`Could not resolve from name '${name}'`); } - public static fromValue(value: ClassConstructor): string { + public fromValue(value: ClassConstructor): string { for (const subType of this.discriminatorMap) { if (subType.value === value) { return subType.name; @@ -34,7 +34,7 @@ export default abstract class ObjectDiscriminator { throw new Error(`Could not resolve from value '${value.name}'`); } - public static createClassTransformerTypeDiscriminator(typePropertyName: string): TypeOptions { + public createClassTransformerTypeDiscriminator(typePropertyName: string): TypeOptions { return { discriminator: { property: typePropertyName, diff --git a/src/settings/deviceSource.ts b/src/settings/deviceSource.ts index 3519a253..25b45f3b 100644 --- a/src/settings/deviceSource.ts +++ b/src/settings/deviceSource.ts @@ -16,7 +16,7 @@ export default class DeviceSource @Expose({ name: 'enabled' }) private readonly _enabled: boolean; - public constructor(id: string, type: string, config: JsonObject, enabled: boolean = true) { + public constructor(id: string, type: string, config: JsonObject, enabled = true) { this._id = id; this._type = type; this._config = config; diff --git a/src/settings/knownDevice.ts b/src/settings/knownDevice.ts index 76f6582f..73454c43 100644 --- a/src/settings/knownDevice.ts +++ b/src/settings/knownDevice.ts @@ -24,7 +24,7 @@ export default class KnownDevice private readonly _enabled: boolean; public constructor( - id: DeviceId, name: string, type: string, source: string, config: JsonObject = {}, enabled: boolean = true + id: DeviceId, name: string, type: string, source: string, config: JsonObject = {}, enabled = true ) { this._id = id; this._name = name; diff --git a/src/socket/types.ts b/src/socket/types.ts index 4b81dab6..c70eaa53 100644 --- a/src/socket/types.ts +++ b/src/socket/types.ts @@ -10,11 +10,11 @@ import { DeviceId } from '../device/deviceId.js'; export type DeviceUpdateData = { deviceId: DeviceId, data: DeviceData } -export interface ClientToServerEvents { +export type ClientToServerEvents = { [WebSocketEvent.deviceUpdateReceived]: (data: DeviceUpdateData) => void; } -export interface ServerToClientEvents { +export type ServerToClientEvents = { [WebSocketEvent.deviceConnected]: (data: SerializedDevice) => void; [WebSocketEvent.deviceDisconnected]: (data: SerializedDevice) => void; [WebSocketEvent.deviceRefreshed]: (data: SerializedDevice) => void; diff --git a/src/types.d.ts b/src/types.d.ts index 15fadf36..75a8d989 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -1,4 +1,4 @@ -export type JsonObject = { [key: string]: JsonValue }; +export type JsonObject = { [key: string]: JsonValue } export type JsonValue = | null diff --git a/src/util/async.ts b/src/util/async.ts index f9985b7f..50ac1a76 100644 --- a/src/util/async.ts +++ b/src/util/async.ts @@ -32,7 +32,7 @@ export const asyncHandler = ( }; }; -export type IntervalAsync = { clear: () => void }; +export type IntervalAsync = { clear: () => void } export const setIntervalAsync = ( fn: (...args: TArgs) => Promise, diff --git a/src/util/devNullStream.ts b/src/util/devNullStream.ts index 07ab9d8e..be9af42f 100644 --- a/src/util/devNullStream.ts +++ b/src/util/devNullStream.ts @@ -4,7 +4,7 @@ export default class DevNullStream extends Writable { private readonly timeoutMs: number; private timer?: NodeJS.Timeout; - public constructor(timeoutMs: number = 500) { + public constructor(timeoutMs = 500) { super(); this.timeoutMs = timeoutMs; this.resetTimer(); diff --git a/tsconfig.json b/tsconfig.json index 3e6bd4b5..72ffcc40 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,13 +3,20 @@ "module": "NodeNext", "moduleResolution": "NodeNext", "target": "ES2022", - "noImplicitAny": true, "noImplicitOverride": true, "allowSyntheticDefaultImports": true, "sourceMap": true, "experimentalDecorators": true, "forceConsistentCasingInFileNames": true, "strict": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictBindCallApply": true, + "strictPropertyInitialization": true, + "noImplicitAny": true, + "noImplicitThis": true, + "alwaysStrict": true, + "useUnknownInCatchVariables": true, "resolveJsonModule": true, "esModuleInterop": true, "types": [