From: Jérôme Benoit Date: Fri, 3 Apr 2026 14:27:05 +0000 (+0200) Subject: refactor: use string/array helper functions consistently X-Git-Tag: ocpp-server@v4.3.0~17 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=157786a376b410b1a72e6e3fbd6319fbd7749e56;p=e-mobility-charging-stations-simulator.git refactor: use string/array helper functions consistently Replace 9 manual .trim().length checks with isEmpty() and isNotEmptyString() helpers. Replace Array.isArray+length guards with isNotEmptyArray() in StatisticUtils. Simplify isValidIdentifierValue to delegate to isNotEmptyString. Replace hardcoded SecurityCtrlr.OrganizationName string with OCPP20ComponentName/RequiredVariableName enums. --- diff --git a/src/charging-station/ocpp/2.0/OCPP20CertificateManager.ts b/src/charging-station/ocpp/2.0/OCPP20CertificateManager.ts index a81e8857..9468f1b6 100644 --- a/src/charging-station/ocpp/2.0/OCPP20CertificateManager.ts +++ b/src/charging-station/ocpp/2.0/OCPP20CertificateManager.ts @@ -16,7 +16,7 @@ import { HashAlgorithmEnumType, InstallCertificateUseEnumType, } from '../../../types/index.js' -import { convertToDate, getErrorMessage } from '../../../utils/index.js' +import { convertToDate, getErrorMessage, isEmpty } from '../../../utils/index.js' /** * Interface for ChargingStation with certificate manager @@ -439,7 +439,7 @@ export class OCPP20CertificateManager { return false } - if (pemData.trim().length === 0) { + if (isEmpty(pemData)) { return false } diff --git a/src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts b/src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts index 03c3d3f6..a175e806 100644 --- a/src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts +++ b/src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts @@ -131,6 +131,8 @@ import { convertToDate, convertToIntOrNaN, generateUUID, + isEmpty, + isNotEmptyString, logger, promiseWithTimeout, sleep, @@ -2815,7 +2817,7 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService { ) // C10: Validate signing certificate PEM format if present - if (firmware.signingCertificate != null && firmware.signingCertificate.trim() !== '') { + if (isNotEmptyString(firmware.signingCertificate)) { if ( !hasCertificateManager(chargingStation) || !chargingStation.certificateManager.validateCertificateFormat(firmware.signingCertificate) @@ -3478,7 +3480,7 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService { if (checkAborted()) return // H9: If firmware location is empty or malformed, send DownloadFailed and stop - if (location.trim() === '' || !this.isValidFirmwareLocation(location)) { + if (isEmpty(location) || !this.isValidFirmwareLocation(location)) { // L01.FR.30: Simulate download retries before reporting DownloadFailed const maxRetries = retries ?? 0 const retryDelayMs = secondsToMilliseconds(retryInterval ?? 0) diff --git a/src/charging-station/ocpp/2.0/OCPP20RequestService.ts b/src/charging-station/ocpp/2.0/OCPP20RequestService.ts index ab9640e0..980aecb0 100644 --- a/src/charging-station/ocpp/2.0/OCPP20RequestService.ts +++ b/src/charging-station/ocpp/2.0/OCPP20RequestService.ts @@ -10,7 +10,9 @@ import { ErrorType, type JsonObject, type JsonType, + OCPP20ComponentName, OCPP20RequestCommand, + OCPP20RequiredVariableName, type OCPP20SignCertificateRequest, type OCPP20StatusNotificationRequest, type OCPP20TransactionEventOptions, @@ -168,7 +170,10 @@ export class OCPP20RequestService extends OCPPRequestService { case OCPP20RequestCommand.SIGN_CERTIFICATE: { let csr: string try { - const configKey = getConfigurationKey(chargingStation, 'SecurityCtrlr.OrganizationName') + const configKey = getConfigurationKey( + chargingStation, + `${OCPP20ComponentName.SecurityCtrlr}.${OCPP20RequiredVariableName.OrganizationName}` + ) const orgName = configKey?.value ?? 'Unknown' const stationId = chargingStation.stationInfo?.chargingStationId ?? 'Unknown' diff --git a/src/charging-station/ocpp/2.0/OCPP20VariableRegistry.ts b/src/charging-station/ocpp/2.0/OCPP20VariableRegistry.ts index cb9698b4..f8819f8c 100644 --- a/src/charging-station/ocpp/2.0/OCPP20VariableRegistry.ts +++ b/src/charging-station/ocpp/2.0/OCPP20VariableRegistry.ts @@ -22,7 +22,7 @@ import { ReasonCodeEnumType, type VariableName, } from '../../../types/index.js' -import { Constants, convertToIntOrNaN, has } from '../../../utils/index.js' +import { Constants, convertToIntOrNaN, has, isEmpty } from '../../../utils/index.js' import { OCPP20Constants } from './OCPP20Constants.js' /** @@ -2697,7 +2697,7 @@ export function validateValue ( } case DataEnumType.MemberList: case DataEnumType.SequenceList: { - if (rawValue.trim().length === 0) { + if (isEmpty(rawValue)) { return { info: 'List cannot be empty', ok: false, reason: ReasonCodeEnumType.InvalidValue } } if (rawValue.startsWith(',') || rawValue.endsWith(',')) { diff --git a/src/charging-station/ocpp/auth/utils/AuthValidators.ts b/src/charging-station/ocpp/auth/utils/AuthValidators.ts index f3b238a5..1961bf6a 100644 --- a/src/charging-station/ocpp/auth/utils/AuthValidators.ts +++ b/src/charging-station/ocpp/auth/utils/AuthValidators.ts @@ -1,5 +1,6 @@ import type { AuthConfiguration, Identifier } from '../types/AuthTypes.js' +import { isNotEmptyString } from '../../../../utils/index.js' import { IdentifierType } from '../types/AuthTypes.js' /** @@ -51,12 +52,7 @@ function isValidConnectorId (connectorId: number | undefined): boolean { * @returns True if the value is a non-empty string with at least one non-whitespace character, false otherwise */ function isValidIdentifierValue (value: string): boolean { - if (typeof value !== 'string' || value.length === 0) { - return false - } - - // Must contain at least one non-whitespace character - return value.trim().length > 0 + return isNotEmptyString(value) } /** diff --git a/src/utils/Configuration.ts b/src/utils/Configuration.ts index 0c706ac7..27f2604e 100644 --- a/src/utils/Configuration.ts +++ b/src/utils/Configuration.ts @@ -35,7 +35,7 @@ import { } from './ConfigurationUtils.js' import { Constants } from './Constants.js' import { ensureError, handleFileException } from './ErrorUtils.js' -import { has, isCFEnvironment, mergeDeepRight, once } from './Utils.js' +import { has, isCFEnvironment, isNotEmptyString, mergeDeepRight, once } from './Utils.js' type ConfigurationSectionType = | LogConfiguration @@ -130,8 +130,7 @@ export class Configuration { public static getConfigurationData (): ConfigurationData | undefined { if ( Configuration.configurationData == null && - Configuration.configurationFile != null && - Configuration.configurationFile.trim().length > 0 + isNotEmptyString(Configuration.configurationFile) ) { try { Configuration.configurationData = JSON.parse( @@ -353,10 +352,7 @@ export class Configuration { } private static getConfigurationFileWatcher (): FSWatcher | undefined { - if ( - Configuration.configurationFile == null || - Configuration.configurationFile.trim().length === 0 - ) { + if (!isNotEmptyString(Configuration.configurationFile)) { return } try { diff --git a/src/utils/ConfigurationMigration.ts b/src/utils/ConfigurationMigration.ts index 65f34d32..50dbcd32 100644 --- a/src/utils/ConfigurationMigration.ts +++ b/src/utils/ConfigurationMigration.ts @@ -7,7 +7,7 @@ import { } from '../types/index.js' import { WorkerProcessType } from '../worker/index.js' import { logPrefix } from './ConfigurationUtils.js' -import { has } from './Utils.js' +import { has, isNotEmptyString } from './Utils.js' /** * Check and warn about deprecated configuration keys @@ -198,7 +198,7 @@ function warnDeprecatedConfigurationKey ( console.error( `${chalk.green(logPrefix())} ${chalk.red( `Deprecated configuration key '${key}' usage in section '${configurationSection}'${ - logMsgToAppend.trim().length > 0 ? `. ${logMsgToAppend}` : '' + isNotEmptyString(logMsgToAppend) ? `. ${logMsgToAppend}` : '' }` )}` ) @@ -206,7 +206,7 @@ function warnDeprecatedConfigurationKey ( console.error( `${chalk.green(logPrefix())} ${chalk.red( `Deprecated configuration key '${key}' usage${ - logMsgToAppend.trim().length > 0 ? `. ${logMsgToAppend}` : '' + isNotEmptyString(logMsgToAppend) ? `. ${logMsgToAppend}` : '' }` )}` ) diff --git a/src/utils/StatisticUtils.ts b/src/utils/StatisticUtils.ts index 75966064..f835e517 100644 --- a/src/utils/StatisticUtils.ts +++ b/src/utils/StatisticUtils.ts @@ -1,5 +1,7 @@ +import { isNotEmptyArray } from './Utils.js' + export const average = (dataSet: number[]): number => { - if (!Array.isArray(dataSet) || dataSet.length === 0) { + if (!isNotEmptyArray(dataSet)) { return 0 } if (dataSet.length === 1) { @@ -9,7 +11,7 @@ export const average = (dataSet: number[]): number => { } export const median = (dataSet: number[]): number => { - if (!Array.isArray(dataSet) || dataSet.length === 0) { + if (!isNotEmptyArray(dataSet)) { return 0 } if (dataSet.length === 1) {