ocpp-ws-io 2.1.6 → 2.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5117,13 +5117,11 @@ interface CORSOptions {
5117
5117
  /** Allowed WebSocket protocol schemes */
5118
5118
  allowedSchemes?: ("ws" | "wss")[];
5119
5119
  }
5120
- interface ServerOptions {
5120
+ interface ServerOptionsBase {
5121
5121
  /** OCPP Security Profile (default: NONE) */
5122
5122
  securityProfile?: SecurityProfile;
5123
5123
  /** TLS options for HTTPS server (Profile 2 & 3) */
5124
5124
  tls?: TLSOptions;
5125
- /** Accepted OCPP subprotocols */
5126
- protocols?: AnyOCPPProtocol[];
5127
5125
  /** Call timeout in ms — inherited by server clients (default: 30000) */
5128
5126
  callTimeoutMs?: number;
5129
5127
  /** Ping interval in ms — inherited by server clients (default: 30000) */
@@ -5132,8 +5130,6 @@ interface ServerOptions {
5132
5130
  deferPingsOnActivity?: boolean;
5133
5131
  /** Max concurrent outbound calls — inherited (default: 1) */
5134
5132
  callConcurrency?: number;
5135
- /** Enable strict mode — inherited (default: false) */
5136
- strictMode?: boolean | OCPPProtocol[];
5137
5133
  /** If defined, restricts strict mode validation ONLY to these methods */
5138
5134
  strictModeMethods?: Array<AllMethodNames<OCPPProtocol>>;
5139
5135
  /** Custom validators — inherited */
@@ -5187,13 +5183,24 @@ interface ServerOptions {
5187
5183
  */
5188
5184
  healthEndpoint?: boolean;
5189
5185
  /**
5190
- * I1: Maximum WebSocket payload size in bytes. Messages exceeding this limit
5186
+ * Maximum WebSocket payload size in bytes. Messages exceeding this limit
5191
5187
  * are rejected at the transport layer before JSON parsing, preventing OOM
5192
5188
  * from oversized or malicious payloads.
5193
5189
  * (default: 65536 / 64KB — sufficient for any standard OCPP message)
5194
5190
  */
5195
5191
  maxPayloadBytes?: number;
5196
5192
  }
5193
+ /** When strictMode is enabled, protocols MUST be specified */
5194
+ interface StrictServerOptions extends ServerOptionsBase {
5195
+ strictMode: true | OCPPProtocol[];
5196
+ protocols: AnyOCPPProtocol[];
5197
+ }
5198
+ /** When strictMode is disabled or omitted, protocols are optional */
5199
+ interface RelaxedServerOptions extends ServerOptionsBase {
5200
+ strictMode?: false;
5201
+ protocols?: AnyOCPPProtocol[];
5202
+ }
5203
+ type ServerOptions = StrictServerOptions | RelaxedServerOptions;
5197
5204
  interface OCPPServerStats {
5198
5205
  /** Number of currently connected WebSockets */
5199
5206
  connectedClients: number;
@@ -5117,13 +5117,11 @@ interface CORSOptions {
5117
5117
  /** Allowed WebSocket protocol schemes */
5118
5118
  allowedSchemes?: ("ws" | "wss")[];
5119
5119
  }
5120
- interface ServerOptions {
5120
+ interface ServerOptionsBase {
5121
5121
  /** OCPP Security Profile (default: NONE) */
5122
5122
  securityProfile?: SecurityProfile;
5123
5123
  /** TLS options for HTTPS server (Profile 2 & 3) */
5124
5124
  tls?: TLSOptions;
5125
- /** Accepted OCPP subprotocols */
5126
- protocols?: AnyOCPPProtocol[];
5127
5125
  /** Call timeout in ms — inherited by server clients (default: 30000) */
5128
5126
  callTimeoutMs?: number;
5129
5127
  /** Ping interval in ms — inherited by server clients (default: 30000) */
@@ -5132,8 +5130,6 @@ interface ServerOptions {
5132
5130
  deferPingsOnActivity?: boolean;
5133
5131
  /** Max concurrent outbound calls — inherited (default: 1) */
5134
5132
  callConcurrency?: number;
5135
- /** Enable strict mode — inherited (default: false) */
5136
- strictMode?: boolean | OCPPProtocol[];
5137
5133
  /** If defined, restricts strict mode validation ONLY to these methods */
5138
5134
  strictModeMethods?: Array<AllMethodNames<OCPPProtocol>>;
5139
5135
  /** Custom validators — inherited */
@@ -5187,13 +5183,24 @@ interface ServerOptions {
5187
5183
  */
5188
5184
  healthEndpoint?: boolean;
5189
5185
  /**
5190
- * I1: Maximum WebSocket payload size in bytes. Messages exceeding this limit
5186
+ * Maximum WebSocket payload size in bytes. Messages exceeding this limit
5191
5187
  * are rejected at the transport layer before JSON parsing, preventing OOM
5192
5188
  * from oversized or malicious payloads.
5193
5189
  * (default: 65536 / 64KB — sufficient for any standard OCPP message)
5194
5190
  */
5195
5191
  maxPayloadBytes?: number;
5196
5192
  }
5193
+ /** When strictMode is enabled, protocols MUST be specified */
5194
+ interface StrictServerOptions extends ServerOptionsBase {
5195
+ strictMode: true | OCPPProtocol[];
5196
+ protocols: AnyOCPPProtocol[];
5197
+ }
5198
+ /** When strictMode is disabled or omitted, protocols are optional */
5199
+ interface RelaxedServerOptions extends ServerOptionsBase {
5200
+ strictMode?: false;
5201
+ protocols?: AnyOCPPProtocol[];
5202
+ }
5203
+ type ServerOptions = StrictServerOptions | RelaxedServerOptions;
5197
5204
  interface OCPPServerStats {
5198
5205
  /** Number of currently connected WebSockets */
5199
5206
  connectedClients: number;
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { E as EventAdapterInterface, A as AuthCallback, L as LoggerLike, a as LoggingConfig, M as MiddlewareFunction, b as MiddlewareContext, C as ConnectionMiddleware, T as TypedEventEmitter, S as ServerEvents, c as CORSOptions, R as RouterConfig, O as OCPPProtocol, d as AllMethodNames, e as RouterHandlerContext, f as OCPPRequestType, g as OCPPResponseType, h as RouterWildcardHandler, i as ServerOptions, j as LoggerLikeNotOptional, k as OCPPServerClient, l as OCPPServerStats, m as ListenOptions, n as TLSOptions, o as CloseOptions, p as CallOptions, V as Validator } from './index-1QBeqAuc.mjs';
2
- export { q as AnyOCPPProtocol, r as AuthAccept, s as CallHandler, t as ClientEvents, u as ClientOptions, v as ConnectionContext, w as ConnectionState, H as HandlerContext, x as HandshakeInfo, y as MessageType, z as MiddlewareNext, B as MiddlewareStack, N as NOREPLY, D as OCPP16Methods, F as OCPP201Methods, G as OCPP21Methods, I as OCPPCall, J as OCPPCallError, K as OCPPCallResult, P as OCPPClient, Q as OCPPMessage, U as OCPPMethodMap, W as OCPPProtocolKey, X as RedisAdapter, Y as SecurityProfile, Z as SessionData, _ as WildcardHandler, $ as createValidator } from './index-1QBeqAuc.mjs';
1
+ import { E as EventAdapterInterface, A as AuthCallback, L as LoggerLike, a as LoggingConfig, M as MiddlewareFunction, b as MiddlewareContext, C as ConnectionMiddleware, T as TypedEventEmitter, S as ServerEvents, c as CORSOptions, R as RouterConfig, O as OCPPProtocol, d as AllMethodNames, e as RouterHandlerContext, f as OCPPRequestType, g as OCPPResponseType, h as RouterWildcardHandler, i as ServerOptions, j as LoggerLikeNotOptional, k as OCPPServerClient, l as OCPPServerStats, m as ListenOptions, n as TLSOptions, o as CloseOptions, p as CallOptions, V as Validator } from './index-BRblF1XV.mjs';
2
+ export { q as AnyOCPPProtocol, r as AuthAccept, s as CallHandler, t as ClientEvents, u as ClientOptions, v as ConnectionContext, w as ConnectionState, H as HandlerContext, x as HandshakeInfo, y as MessageType, z as MiddlewareNext, B as MiddlewareStack, N as NOREPLY, D as OCPP16Methods, F as OCPP201Methods, G as OCPP21Methods, I as OCPPCall, J as OCPPCallError, K as OCPPCallResult, P as OCPPClient, Q as OCPPMessage, U as OCPPMethodMap, W as OCPPProtocolKey, X as RedisAdapter, Y as SecurityProfile, Z as SessionData, _ as WildcardHandler, $ as createValidator } from './index-BRblF1XV.mjs';
3
3
  import { Server, IncomingMessage } from 'node:http';
4
4
  import { Duplex } from 'node:stream';
5
5
  import 'ws';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { E as EventAdapterInterface, A as AuthCallback, L as LoggerLike, a as LoggingConfig, M as MiddlewareFunction, b as MiddlewareContext, C as ConnectionMiddleware, T as TypedEventEmitter, S as ServerEvents, c as CORSOptions, R as RouterConfig, O as OCPPProtocol, d as AllMethodNames, e as RouterHandlerContext, f as OCPPRequestType, g as OCPPResponseType, h as RouterWildcardHandler, i as ServerOptions, j as LoggerLikeNotOptional, k as OCPPServerClient, l as OCPPServerStats, m as ListenOptions, n as TLSOptions, o as CloseOptions, p as CallOptions, V as Validator } from './index-1QBeqAuc.js';
2
- export { q as AnyOCPPProtocol, r as AuthAccept, s as CallHandler, t as ClientEvents, u as ClientOptions, v as ConnectionContext, w as ConnectionState, H as HandlerContext, x as HandshakeInfo, y as MessageType, z as MiddlewareNext, B as MiddlewareStack, N as NOREPLY, D as OCPP16Methods, F as OCPP201Methods, G as OCPP21Methods, I as OCPPCall, J as OCPPCallError, K as OCPPCallResult, P as OCPPClient, Q as OCPPMessage, U as OCPPMethodMap, W as OCPPProtocolKey, X as RedisAdapter, Y as SecurityProfile, Z as SessionData, _ as WildcardHandler, $ as createValidator } from './index-1QBeqAuc.js';
1
+ import { E as EventAdapterInterface, A as AuthCallback, L as LoggerLike, a as LoggingConfig, M as MiddlewareFunction, b as MiddlewareContext, C as ConnectionMiddleware, T as TypedEventEmitter, S as ServerEvents, c as CORSOptions, R as RouterConfig, O as OCPPProtocol, d as AllMethodNames, e as RouterHandlerContext, f as OCPPRequestType, g as OCPPResponseType, h as RouterWildcardHandler, i as ServerOptions, j as LoggerLikeNotOptional, k as OCPPServerClient, l as OCPPServerStats, m as ListenOptions, n as TLSOptions, o as CloseOptions, p as CallOptions, V as Validator } from './index-BRblF1XV.js';
2
+ export { q as AnyOCPPProtocol, r as AuthAccept, s as CallHandler, t as ClientEvents, u as ClientOptions, v as ConnectionContext, w as ConnectionState, H as HandlerContext, x as HandshakeInfo, y as MessageType, z as MiddlewareNext, B as MiddlewareStack, N as NOREPLY, D as OCPP16Methods, F as OCPP201Methods, G as OCPP21Methods, I as OCPPCall, J as OCPPCallError, K as OCPPCallResult, P as OCPPClient, Q as OCPPMessage, U as OCPPMethodMap, W as OCPPProtocolKey, X as RedisAdapter, Y as SecurityProfile, Z as SessionData, _ as WildcardHandler, $ as createValidator } from './index-BRblF1XV.js';
3
3
  import { Server, IncomingMessage } from 'node:http';
4
4
  import { Duplex } from 'node:stream';
5
5
  import 'ws';
package/dist/index.js CHANGED
@@ -37739,6 +37739,36 @@ var OCPPClient = class _OCPPClient extends import_node_events.EventEmitter {
37739
37739
  return;
37740
37740
  }
37741
37741
  const messageType = message[0];
37742
+ const messageId = message[1];
37743
+ if (typeof messageId !== "string") {
37744
+ this._onBadMessage(
37745
+ typeof rawData === "string" ? rawData : rawData.toString(),
37746
+ new RPCMessageTypeNotSupportedError(
37747
+ `Invalid MessageId type: ${typeof messageId} (expected string)`
37748
+ )
37749
+ );
37750
+ return;
37751
+ }
37752
+ if (messageType === MessageType.CALL && message.length < 4 || messageType === MessageType.CALLRESULT && message.length < 3 || messageType === MessageType.CALLERROR && message.length < 5) {
37753
+ this._onBadMessage(
37754
+ JSON.stringify(message),
37755
+ new RPCMessageTypeNotSupportedError(
37756
+ `Missing payload elements for message type ${messageType}`
37757
+ )
37758
+ );
37759
+ return;
37760
+ }
37761
+ const payloadIndex = messageType === MessageType.CALLERROR ? 4 : messageType === MessageType.CALL ? 3 : 2;
37762
+ const payload = message[payloadIndex];
37763
+ if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
37764
+ this._onBadMessage(
37765
+ JSON.stringify(message),
37766
+ new RPCMessageTypeNotSupportedError(
37767
+ `Payload must be a JSON object, got ${payload === null ? "null" : Array.isArray(payload) ? "array" : typeof payload}`
37768
+ )
37769
+ );
37770
+ return;
37771
+ }
37742
37772
  switch (messageType) {
37743
37773
  case MessageType.CALL:
37744
37774
  this._handleIncomingCall(message);
@@ -38708,7 +38738,18 @@ var OCPPServerClient = class extends OCPPClient {
38708
38738
  this._onClose(code, reason)
38709
38739
  )
38710
38740
  );
38711
- ws.on("error", (err) => this.emit("error", err));
38741
+ ws.on("error", (err) => {
38742
+ if (this.listenerCount("error") > 0) {
38743
+ this.emit("error", err);
38744
+ } else {
38745
+ this._logger?.debug?.(
38746
+ "WebSocket error (unhandled by client listener)",
38747
+ {
38748
+ error: err.message
38749
+ }
38750
+ );
38751
+ }
38752
+ });
38712
38753
  ws.on("ping", () => {
38713
38754
  this._recordActivity();
38714
38755
  this.emit("ping");
@@ -38816,9 +38857,9 @@ var OCPPServer = class extends import_node_events3.EventEmitter {
38816
38857
  super();
38817
38858
  this.setMaxListeners(0);
38818
38859
  if (options.strictMode) {
38819
- if (!options.strictModeValidators && !options.protocols?.length) {
38860
+ if (!options.protocols?.length) {
38820
38861
  throw new Error(
38821
- "strictMode requires either strictModeValidators or protocols to be specified"
38862
+ "strictMode requires protocols to be specified (e.g. protocols: ['ocpp1.6'])"
38822
38863
  );
38823
38864
  }
38824
38865
  }