refactor: cleanup eslint configuration
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / OCPPResponseService.ts
1 import _Ajv, { type ValidateFunction } from 'ajv'
2 import _ajvFormats from 'ajv-formats'
3
4 import type { ChargingStation } from '../../charging-station/index.js'
5 import { OCPPError } from '../../exception/index.js'
6 import type {
7 IncomingRequestCommand,
8 JsonType,
9 OCPPVersion,
10 RequestCommand
11 } from '../../types/index.js'
12 import { Constants, logger } from '../../utils/index.js'
13 import { OCPPServiceUtils } from './OCPPServiceUtils.js'
14 type Ajv = _Ajv.default
15 // eslint-disable-next-line @typescript-eslint/no-redeclare
16 const Ajv = _Ajv.default
17 const ajvFormats = _ajvFormats.default
18
19 const moduleName = 'OCPPResponseService'
20
21 export abstract class OCPPResponseService {
22 private static instance: OCPPResponseService | null = null
23 private readonly version: OCPPVersion
24 protected readonly ajv: Ajv
25 protected readonly ajvIncomingRequest: Ajv
26 protected abstract payloadValidateFunctions: Map<RequestCommand, ValidateFunction<JsonType>>
27 public abstract incomingRequestResponsePayloadValidateFunctions: Map<
28 IncomingRequestCommand,
29 ValidateFunction<JsonType>
30 >
31
32 protected constructor (version: OCPPVersion) {
33 this.version = version
34 this.ajv = new Ajv({
35 keywords: ['javaType'],
36 multipleOfPrecision: 2
37 })
38 ajvFormats(this.ajv)
39 this.ajvIncomingRequest = new Ajv({
40 keywords: ['javaType'],
41 multipleOfPrecision: 2
42 })
43 ajvFormats(this.ajvIncomingRequest)
44 this.responseHandler = this.responseHandler.bind(this)
45 this.validateResponsePayload = this.validateResponsePayload.bind(this)
46 }
47
48 public static getInstance<T extends OCPPResponseService>(this: new () => T): T {
49 if (OCPPResponseService.instance === null) {
50 OCPPResponseService.instance = new this()
51 }
52 return OCPPResponseService.instance as T
53 }
54
55 protected validateResponsePayload<T extends JsonType>(
56 chargingStation: ChargingStation,
57 commandName: RequestCommand,
58 payload: T
59 ): boolean {
60 if (chargingStation.stationInfo?.ocppStrictCompliance === false) {
61 return true
62 }
63 const validate = this.payloadValidateFunctions.get(commandName)
64 if (validate?.(payload) === true) {
65 return true
66 }
67 logger.error(
68 `${chargingStation.logPrefix()} ${moduleName}.validateResponsePayload: Command '${commandName}' response PDU is invalid: %j`,
69 validate?.errors
70 )
71 throw new OCPPError(
72 OCPPServiceUtils.ajvErrorsToErrorType(validate?.errors),
73 'Response PDU is invalid',
74 commandName,
75 JSON.stringify(validate?.errors, undefined, 2)
76 )
77 }
78
79 protected emptyResponseHandler = Constants.EMPTY_FUNCTION
80
81 public abstract responseHandler<ReqType extends JsonType, ResType extends JsonType>(
82 chargingStation: ChargingStation,
83 commandName: RequestCommand,
84 payload: ResType,
85 requestPayload: ReqType
86 ): Promise<void>
87 }