refactor: refine isNotEmptyString() and isNotEmptyArray() helpers type
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Fri, 23 Aug 2024 18:00:09 +0000 (20:00 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Fri, 23 Aug 2024 18:00:09 +0000 (20:00 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
src/charging-station/ChargingStation.ts
src/charging-station/Helpers.ts
src/charging-station/ocpp/OCPPServiceUtils.ts
src/utils/Utils.ts

index 83e5517b537b696ac6b61c7d984c50347e31b8cf..87dfc50978e79d188ce49044ad69613f19c7e6b7 100644 (file)
@@ -388,7 +388,7 @@ export class ChargingStation extends EventEmitter {
   }
 
   private getConfiguredSupervisionUrl (): URL {
-    let configuredSupervisionUrl: string
+    let configuredSupervisionUrl: string | undefined
     const supervisionUrls = this.stationInfo?.supervisionUrls ?? Configuration.getSupervisionUrls()
     if (isNotEmptyArray(supervisionUrls)) {
       let configuredSupervisionUrlIndex: number
@@ -413,7 +413,7 @@ export class ChargingStation extends EventEmitter {
           break
       }
       configuredSupervisionUrl = supervisionUrls[configuredSupervisionUrlIndex]
-    } else {
+    } else if (typeof supervisionUrls === 'string') {
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       configuredSupervisionUrl = supervisionUrls!
     }
@@ -603,17 +603,16 @@ export class ChargingStation extends EventEmitter {
     stationInfo.chargingStationId = getChargingStationId(this.index, stationTemplate)
     createSerialNumber(stationTemplate, stationInfo)
     stationInfo.voltageOut = this.getVoltageOut(stationInfo)
-    if (isNotEmptyArray(stationTemplate.power)) {
+    if (isNotEmptyArray<number>(stationTemplate.power)) {
       const powerArrayRandomIndex = Math.floor(secureRandom() * stationTemplate.power.length)
       stationInfo.maximumPower =
         stationTemplate.powerUnit === PowerUnits.KILO_WATT
           ? stationTemplate.power[powerArrayRandomIndex] * 1000
           : stationTemplate.power[powerArrayRandomIndex]
-    } else {
+    } else if (typeof stationTemplate.power === 'number') {
       stationInfo.maximumPower =
         stationTemplate.powerUnit === PowerUnits.KILO_WATT
-          ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-          stationTemplate.power! * 1000
+          ? stationTemplate.power * 1000
           : stationTemplate.power
     }
     stationInfo.maximumAmperage = this.getMaximumAmperage(stationInfo)
index 240a54a4f6ff1046d9524eaf4797d202d2ec9f0d..112fb904159c95210b49fa532445fdfc97d70578 100644 (file)
@@ -869,11 +869,11 @@ export const waitChargingStationEvents = async (
 
 const getConfiguredMaxNumberOfConnectors = (stationTemplate: ChargingStationTemplate): number => {
   let configuredMaxNumberOfConnectors = 0
-  if (isNotEmptyArray(stationTemplate.numberOfConnectors)) {
+  if (isNotEmptyArray<number>(stationTemplate.numberOfConnectors)) {
     const numberOfConnectors = stationTemplate.numberOfConnectors
     configuredMaxNumberOfConnectors =
       numberOfConnectors[Math.floor(secureRandom() * numberOfConnectors.length)]
-  } else if (stationTemplate.numberOfConnectors != null) {
+  } else if (typeof stationTemplate.numberOfConnectors === 'number') {
     configuredMaxNumberOfConnectors = stationTemplate.numberOfConnectors
   } else if (stationTemplate.Connectors != null && stationTemplate.Evses == null) {
     configuredMaxNumberOfConnectors =
@@ -1031,7 +1031,7 @@ const getChargingProfilesLimit = (
         start: chargingSchedule.startSchedule,
       })
     ) {
-      if (isNotEmptyArray(chargingSchedule.chargingSchedulePeriod)) {
+      if (isNotEmptyArray<ChargingSchedulePeriod>(chargingSchedule.chargingSchedulePeriod)) {
         const chargingSchedulePeriodCompareFn = (
           a: ChargingSchedulePeriod,
           b: ChargingSchedulePeriod
index 4fa8bbfb7bcdc95c7666c903968eedaf9ef76f5c..d62b81f98f2f0349a4c208d1c840d854dbb61a10 100644 (file)
@@ -1194,7 +1194,7 @@ const getSampledValueTemplate = (
   ) {
     if (
       !OCPPConstants.OCPP_MEASURANDS_SUPPORTED.includes(
-        sampledValueTemplates[index]?.measurand ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
+        sampledValueTemplates[index].measurand ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
       )
     ) {
       logger.warn(
@@ -1202,8 +1202,8 @@ const getSampledValueTemplate = (
       )
     } else if (
       phase != null &&
-      sampledValueTemplates[index]?.phase === phase &&
-      sampledValueTemplates[index]?.measurand === measurand &&
+      sampledValueTemplates[index].phase === phase &&
+      sampledValueTemplates[index].measurand === measurand &&
       getConfigurationKey(
         chargingStation,
         StandardParametersKey.MeterValuesSampledData
@@ -1212,8 +1212,8 @@ const getSampledValueTemplate = (
       return sampledValueTemplates[index]
     } else if (
       phase == null &&
-      sampledValueTemplates[index]?.phase == null &&
-      sampledValueTemplates[index]?.measurand === measurand &&
+      sampledValueTemplates[index].phase == null &&
+      sampledValueTemplates[index].measurand === measurand &&
       getConfigurationKey(
         chargingStation,
         StandardParametersKey.MeterValuesSampledData
@@ -1222,8 +1222,8 @@ const getSampledValueTemplate = (
       return sampledValueTemplates[index]
     } else if (
       measurand === MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER &&
-      (sampledValueTemplates[index]?.measurand == null ||
-        sampledValueTemplates[index]?.measurand === measurand)
+      (sampledValueTemplates[index].measurand == null ||
+        sampledValueTemplates[index].measurand === measurand)
     ) {
       return sampledValueTemplates[index]
     }
index c816cf7150222b6febd2450d01e65388f066fbb5..2da9b1cb0cd784b27deeedd7d21f96a5774e0050 100644 (file)
@@ -13,7 +13,7 @@ import {
 } from 'date-fns'
 import { getRandomValues, randomBytes, randomUUID } from 'node:crypto'
 import { env, nextTick } from 'node:process'
-import { is } from 'rambda'
+import { is, isNotEmpty, type NonEmptyArray, type ReadonlyNonEmptyArray } from 'rambda'
 
 import {
   type JsonType,
@@ -230,12 +230,16 @@ export const isCFEnvironment = (): boolean => {
   return env.VCAP_APPLICATION != null
 }
 
-export const isNotEmptyString = (value: unknown): value is string => {
+declare const nonEmptyString: unique symbol
+type NonEmptyString = { [nonEmptyString]: true } & string
+export const isNotEmptyString = (value: unknown): value is NonEmptyString => {
   return typeof value === 'string' && value.trim().length > 0
 }
 
-export const isNotEmptyArray = (value: unknown): value is unknown[] => {
-  return Array.isArray(value) && value.length > 0
+export const isNotEmptyArray = <T>(
+  value: unknown
+): value is NonEmptyArray<T> | ReadonlyNonEmptyArray<T> => {
+  return Array.isArray(value) && isNotEmpty<T>(value as T[])
 }
 
 export const insertAt = (str: string, subStr: string, pos: number): string =>