UNPKG

ocpp-rpc

Version:

A client & server implementation of the WAMP-like RPC-over-websocket system defined in the OCPP protocols (e.g. OCPP1.6-J and OCPP2.0.1).

83 lines (70 loc) 2.87 kB
const Ajv = require('ajv'); const addFormats = require('ajv-formats'); const { createRPCError } = require('./util'); const errorCodeLUT = { 'maximum' : "FormatViolation", 'minimum' : "FormatViolation", 'maxLength' : "FormatViolation", 'minLength' : "FormatViolation", 'exclusiveMaximum' : "OccurenceConstraintViolation", 'exclusiveMinimum' : "OccurenceConstraintViolation", 'multipleOf' : "OccurenceConstraintViolation", 'maxItems' : "OccurenceConstraintViolation", 'minItems' : "OccurenceConstraintViolation", 'maxProperties' : "OccurenceConstraintViolation", 'minProperties' : "OccurenceConstraintViolation", 'additionalItems' : "OccurenceConstraintViolation", 'required' : "OccurenceConstraintViolation", 'pattern' : "PropertyConstraintViolation", 'propertyNames' : "PropertyConstraintViolation", 'additionalProperties' : "PropertyConstraintViolation", 'type' : "TypeConstraintViolation", }; class Validator { constructor(subprotocol, ajv) { this._subprotocol = subprotocol; this._ajv = ajv; } get subprotocol() { return this._subprotocol; } validate(schemaId, params) { const validator = this._ajv.getSchema(schemaId); if (!validator) { throw createRPCError("ProtocolError", `Schema '${schemaId}' is missing from subprotocol schema '${this._subprotocol}'`); } const res = validator(params); if (!res && validator.errors?.length > 0) { const [first] = validator.errors; const rpcErrorCode = errorCodeLUT[first.keyword] ?? "FormatViolation"; throw createRPCError(rpcErrorCode, this._ajv.errorsText(validator.errors), { errors: validator.errors, data: params, }); } return res; } } function createValidator(subprotocol, json) { const ajv = new Ajv({strictSchema: false}); addFormats(ajv); ajv.addSchema(json); ajv.removeKeyword("multipleOf"); ajv.addKeyword({ keyword: "multipleOf", type: "number", compile(schema) { return data => { const result = data / schema; const epsilon = 1e-6; // small value to account for floating point precision errors return Math.abs(Math.round(result) - result) < epsilon; }; }, errors: false, metaSchema: { type: "number", }, }); return new Validator(subprotocol, ajv); } module.exports = {Validator, createValidator};