ocpp-ws-io 1.0.0-alpha → 1.0.0

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.

Potentially problematic release.


This version of ocpp-ws-io might be problematic. Click here for more details.

@@ -46,6 +46,11 @@ jobs:
46
46
  fi
47
47
  echo "Publishing $VERSION with tag: $(cat $GITHUB_OUTPUT | grep tag | cut -d= -f2)"
48
48
 
49
+ - name: Sync version from git tag to package.json
50
+ run: |
51
+ VERSION="${GITHUB_REF#refs/tags/v}"
52
+ npm version "$VERSION" --no-git-tag-version --allow-same-version
53
+
49
54
  - name: Publish to npm
50
55
  run: npm publish --provenance --access public --tag ${{ steps.dist-tag.outputs.tag }}
51
56
  env:
package/README.md CHANGED
@@ -12,7 +12,8 @@ Built with TypeScript from the ground up — supports OCPP 1.6, 2.0.1, and 2.1 w
12
12
  - 🔁 **Auto-Reconnect** — Exponential backoff with configurable limits
13
13
  - 🧩 **Framework Agnostic** — Use standalone, or attach to Express, Fastify, NestJS, etc.
14
14
  - 📡 **Clustering** — Optional Redis adapter for multi-instance deployments
15
- - 🎯 **Type-Safe** — Full TypeScript types for events, handlers, options, and messages
15
+ - 🎯 **Type-Safe** — Auto-generated types for all OCPP 1.6, 2.0.1 & 2.1 methods with full request/response inference
16
+ - 🔀 **Version-Aware Handlers** — Register handlers per OCPP version with typed params, or use generic handlers with protocol context
16
17
 
17
18
  ## Installation
18
19
 
@@ -34,21 +35,21 @@ const client = new OCPPClient({
34
35
  securityProfile: SecurityProfile.NONE,
35
36
  });
36
37
 
37
- // Register a handler for incoming calls from the server
38
- client.handle("Reset", ({ params }) => {
39
- console.log("Reset requested:", params);
38
+ // Register a handler params are auto-typed for OCPP 1.6 Reset
39
+ client.handle("Reset", ({ params, protocol }) => {
40
+ console.log(`Reset requested (${protocol}):`, params.type);
40
41
  return { status: "Accepted" };
41
42
  });
42
43
 
43
- // Connect and send a BootNotification
44
+ // Connect and send a BootNotification — version-aware, fully typed
44
45
  await client.connect();
45
46
 
46
- const response = await client.call("BootNotification", {
47
+ const response = await client.call("ocpp1.6", "BootNotification", {
47
48
  chargePointVendor: "VendorX",
48
49
  chargePointModel: "ModelY",
49
50
  });
50
51
 
51
- console.log("BootNotification response:", response);
52
+ console.log("Status:", response.status); // typed: "Accepted" | "Pending" | "Rejected"
52
53
  ```
53
54
 
54
55
  ### Server (Central System)
@@ -77,9 +78,9 @@ server.auth((accept, reject, handshake) => {
77
78
  server.on("client", (client) => {
78
79
  console.log(`${client.identity} connected (protocol: ${client.protocol})`);
79
80
 
80
- // Handle BootNotification from this client
81
- client.handle("BootNotification", ({ params }) => {
82
- console.log("BootNotification:", params);
81
+ // Version-aware handlers params typed per OCPP version
82
+ client.handle("ocpp1.6", "BootNotification", ({ params }) => {
83
+ console.log("OCPP 1.6 Boot:", params.chargePointVendor);
83
84
  return {
84
85
  status: "Accepted",
85
86
  currentTime: new Date().toISOString(),
@@ -87,11 +88,20 @@ server.on("client", (client) => {
87
88
  };
88
89
  });
89
90
 
90
- // Send a call TO the client
91
- client
92
- .call("GetConfiguration", { key: ["HeartbeatInterval"] })
93
- .then((result) => console.log("GetConfiguration result:", result))
94
- .catch((err) => console.error("GetConfiguration failed:", err));
91
+ client.handle("ocpp2.0.1", "BootNotification", ({ params }) => {
92
+ console.log("OCPP 2.0.1 Boot:", params.chargingStation.vendorName);
93
+ return {
94
+ status: "Accepted",
95
+ currentTime: new Date().toISOString(),
96
+ interval: 300,
97
+ };
98
+ });
99
+
100
+ // Version-aware call from server to client
101
+ const config = await client.call("ocpp1.6", "GetConfiguration", {
102
+ key: ["HeartbeatInterval"],
103
+ });
104
+ console.log("Config:", config.configurationKey);
95
105
 
96
106
  client.on("close", () => {
97
107
  console.log(`${client.identity} disconnected`);
@@ -289,6 +299,122 @@ httpServer.listen(3000);
289
299
 
290
300
  ---
291
301
 
302
+ ## Type-Safe API
303
+
304
+ `ocpp-ws-io` includes auto-generated TypeScript types for **all** OCPP methods across 1.6, 2.0.1, and 2.1. When you call `handle()` or `call()` with a known method name, both request params and response types are inferred automatically. Custom/vendor-specific methods are also supported — they use `Record<string, any>` params.
305
+
306
+ ### Version-Aware `handle()` and `call()`
307
+
308
+ Both `handle()` and `call()` support **version-specific overloads** — params and response types are inferred from the OCPP version you specify:
309
+
310
+ ```typescript
311
+ // ✅ Version-aware handle — params typed per version
312
+ client.handle("ocpp1.6", "BootNotification", ({ params }) => {
313
+ params.chargePointVendor; // ✅ string (OCPP 1.6 shape)
314
+ return { status: "Accepted", currentTime: "...", interval: 300 };
315
+ });
316
+
317
+ client.handle("ocpp2.0.1", "BootNotification", ({ params }) => {
318
+ params.chargingStation; // ✅ { model, vendorName } (OCPP 2.0.1 shape)
319
+ return { status: "Accepted", currentTime: "...", interval: 300 };
320
+ });
321
+
322
+ // ✅ Version-aware call — params and response typed per version
323
+ const res16 = await client.call("ocpp1.6", "BootNotification", {
324
+ chargePointVendor: "VendorX",
325
+ chargePointModel: "ModelY",
326
+ });
327
+ res16.status; // typed: "Accepted" | "Pending" | "Rejected"
328
+
329
+ const res201 = await client.call("ocpp2.0.1", "BootNotification", {
330
+ chargingStation: { model: "ModelX", vendorName: "VendorY" },
331
+ reason: "PowerUp",
332
+ });
333
+ res201.status; // typed for 2.0.1
334
+ ```
335
+
336
+ ### Default Protocol and Untyped Calls
337
+
338
+ ```typescript
339
+ // Default protocol — uses the client's type parameter P
340
+ const res = await client.call("BootNotification", {
341
+ chargePointVendor: "VendorX",
342
+ chargePointModel: "ModelY",
343
+ });
344
+
345
+ // Custom/extension methods — loose typing
346
+ client.handle("VendorCustomAction", ({ params }) => {
347
+ params; // Record<string, any>
348
+ return { result: "ok" };
349
+ });
350
+
351
+ const custom = await client.call<{ result: string }>("VendorCustomAction", {
352
+ data: "hello",
353
+ });
354
+ custom.result; // string
355
+ ```
356
+
357
+ ````
358
+
359
+ **Dispatch priority**: When a call arrives, the runtime looks up handlers in this order:
360
+
361
+ 1. **Version-specific** handler (e.g., `"ocpp1.6:BootNotification"`)
362
+ 2. **Generic** handler (e.g., `"BootNotification"`)
363
+ 3. **Wildcard** handler
364
+
365
+ ### Handler Context
366
+
367
+ Every handler receives a `HandlerContext` with:
368
+
369
+ ```typescript
370
+ client.handle("Reset", ({ params, protocol, method, messageId, signal }) => {
371
+ params; // typed request body
372
+ protocol; // "ocpp1.6" | "ocpp2.0.1" | "ocpp2.1" | undefined
373
+ method; // "Reset"
374
+ messageId; // unique call ID
375
+ signal; // AbortSignal
376
+ return { status: "Accepted" };
377
+ });
378
+ ````
379
+
380
+ ### `removeHandler` with Version Support
381
+
382
+ ```typescript
383
+ // Remove a generic handler
384
+ client.removeHandler("Reset");
385
+
386
+ // Remove a version-specific handler
387
+ client.removeHandler("ocpp1.6", "Reset");
388
+
389
+ // Remove wildcard handler
390
+ client.removeHandler();
391
+
392
+ // Remove all handlers
393
+ client.removeAllHandlers();
394
+ ```
395
+
396
+ ### Available Generated Type Utilities
397
+
398
+ ```typescript
399
+ import type {
400
+ OCPPProtocol, // "ocpp1.6" | "ocpp2.0.1" | "ocpp2.1"
401
+ AllMethodNames, // All method names for a given protocol
402
+ OCPPRequestType, // Request type for a method, e.g. OCPPRequestType<"ocpp1.6", "Reset">
403
+ OCPPResponseType, // Response type for a method
404
+ OCPPMethodMap, // Full method map for a protocol
405
+ } from "ocpp-ws-io";
406
+
407
+ // Example: Get all method names for OCPP 1.6
408
+ type OCPP16Methods = AllMethodNames<"ocpp1.6">;
409
+ // "Authorize" | "BootNotification" | "ChangeAvailability" | ...
410
+
411
+ // Example: Get request params type
412
+ type BootReq = OCPPRequestType<"ocpp1.6", "BootNotification">;
413
+ // { chargePointVendor: string; chargePointModel: string; ... }
414
+ ```
415
+
416
+ ---
417
+
292
418
  ## Strict Mode (Schema Validation)
293
419
 
294
420
  Enable strict mode to validate all inbound and outbound messages against the OCPP JSON schemas:
@@ -429,18 +555,45 @@ const client = new OCPPClient(options: ClientOptions);
429
555
  // Connect to the OCPP server
430
556
  await client.connect();
431
557
 
432
- // Make an RPC call
433
- const result = await client.call('BootNotification', { ... });
558
+ // Version-aware call fully typed params and response
559
+ const result = await client.call("ocpp1.6", "BootNotification", {
560
+ chargePointVendor: "VendorX",
561
+ chargePointModel: "ModelY",
562
+ });
563
+
564
+ // OCPP 2.0.1 — different shape, still fully typed
565
+ const result201 = await client.call("ocpp2.0.1", "BootNotification", {
566
+ chargingStation: { model: "ModelX", vendorName: "VendorY" },
567
+ reason: "PowerUp",
568
+ });
569
+
570
+ // Default protocol call (uses the client's type parameter P)
571
+ const res = await client.call("Heartbeat", {});
572
+
573
+ // Explicit response type (for custom/vendor methods)
574
+ const custom = await client.call<{ result: string }>("VendorAction", {
575
+ data: "hello",
576
+ });
434
577
 
435
- // Make a call with options
436
- const result = await client.call('RemoteStartTransaction', params, {
578
+ // Call with options
579
+ const res2 = await client.call("ocpp1.6", "RemoteStartTransaction", params, {
437
580
  timeoutMs: 5000,
438
- signal: abortController.signal,
439
581
  });
440
582
 
441
- // Register a handler for a specific method
442
- client.handle('Reset', ({ params, method, messageId, signal }) => {
443
- return { status: 'Accepted' };
583
+ // Register a typed handler for a specific method
584
+ client.handle("Reset", ({ params, protocol, method, messageId, signal }) => {
585
+ return { status: "Accepted" };
586
+ });
587
+
588
+ // Register a version-specific handler
589
+ client.handle("ocpp1.6", "BootNotification", ({ params }) => {
590
+ params.chargePointVendor; // typed for OCPP 1.6 only
591
+ return { status: "Accepted", currentTime: "...", interval: 300 };
592
+ });
593
+
594
+ // Register a handler for a custom/vendor method
595
+ client.handle("VendorCustomAction", ({ params }) => {
596
+ return { result: "ok" };
444
597
  });
445
598
 
446
599
  // Register a wildcard handler (handles all unmatched methods)
@@ -449,21 +602,23 @@ client.handle((method, { params }) => {
449
602
  throw new RPCNotImplementedError();
450
603
  });
451
604
 
452
- // Remove a handler
453
- client.removeHandler('Reset');
454
- client.removeAllHandlers();
605
+ // Remove handlers
606
+ client.removeHandler("Reset"); // remove generic
607
+ client.removeHandler("ocpp1.6", "Reset"); // remove version-specific
608
+ client.removeHandler(); // remove wildcard
609
+ client.removeAllHandlers(); // remove all
455
610
 
456
611
  // Close the connection
457
612
  await client.close();
458
- await client.close({ code: 1000, reason: 'Normal closure' });
613
+ await client.close({ code: 1000, reason: "Normal closure" });
459
614
  await client.close({ awaitPending: true }); // wait for in-flight calls
460
- await client.close({ force: true }); // immediate termination
615
+ await client.close({ force: true }); // immediate termination
461
616
 
462
617
  // Reconfigure at runtime
463
618
  client.reconfigure({ callTimeoutMs: 10000 });
464
619
 
465
620
  // Send a raw message (advanced — use with caution)
466
- client.sendRaw(JSON.stringify([2, 'uuid', 'Heartbeat', {}]));
621
+ client.sendRaw(JSON.stringify([2, "uuid", "Heartbeat", {}]));
467
622
  ```
468
623
 
469
624
  #### Events
@@ -604,9 +759,11 @@ server.on("client", (client) => {
604
759
  client.session; // Record<string, unknown> — session data from auth
605
760
  client.handshake; // HandshakeInfo — connection handshake details
606
761
 
607
- // All OCPPClient methods available:
608
- client.handle("Heartbeat", () => ({ currentTime: new Date().toISOString() }));
609
- const result = await client.call("GetConfiguration", { key: [] });
762
+ // All OCPPClient methods available — version-aware:
763
+ client.handle("ocpp1.6", "Heartbeat", () => ({
764
+ currentTime: new Date().toISOString(),
765
+ }));
766
+ const result = await client.call("ocpp1.6", "GetConfiguration", { key: [] });
610
767
  await client.close();
611
768
  });
612
769
  ```
@@ -727,6 +884,13 @@ All types are exported for use in your application:
727
884
 
728
885
  ```typescript
729
886
  import type {
887
+ // OCPP protocol types (auto-generated)
888
+ OCPPProtocol, // "ocpp1.6" | "ocpp2.0.1" | "ocpp2.1"
889
+ AllMethodNames, // Union of method names for a protocol
890
+ OCPPRequestType, // Request type for a method + protocol
891
+ OCPPResponseType, // Response type for a method + protocol
892
+ OCPPMethodMap, // Full method map for a protocol
893
+
730
894
  // OCPP message types
731
895
  OCPPCall,
732
896
  OCPPCallResult,
@@ -755,6 +919,10 @@ import type {
755
919
  // Event types
756
920
  ClientEvents,
757
921
  ServerEvents,
922
+ TypedEventEmitter,
923
+
924
+ // Server client interface
925
+ ServerClientInstance,
758
926
 
759
927
  // Adapter interface (for custom adapters)
760
928
  EventAdapterInterface,
@@ -768,6 +936,10 @@ import type {
768
936
  - **Node.js** ≥ 18.0.0
769
937
  - **TypeScript** ≥ 5.0 (optional, but recommended)
770
938
 
939
+ ## Inspired By
940
+
941
+ This project is inspired by [ocpp-rpc](https://github.com/mikuso/ocpp-rpc) — a well-crafted OCPP-J RPC library for Node.js. `ocpp-ws-io` builds on similar ideas while adding full TypeScript type safety, version-aware APIs, built-in schema validation, and clustering support.
942
+
771
943
  ## License
772
944
 
773
945
  [MIT](LICENSE)
@@ -1,8 +1,9 @@
1
- import { E as EventAdapterInterface } from '../types-6LVUoXof.mjs';
1
+ import { E as EventAdapterInterface } from '../types-CpxyZ6AL.mjs';
2
2
  import 'node:https';
3
3
  import 'node:http';
4
4
  import 'node:tls';
5
5
  import 'node:stream';
6
+ import 'node:events';
6
7
  import 'ajv';
7
8
 
8
9
  /**
@@ -1,8 +1,9 @@
1
- import { E as EventAdapterInterface } from '../types-6LVUoXof.js';
1
+ import { E as EventAdapterInterface } from '../types-CpxyZ6AL.js';
2
2
  import 'node:https';
3
3
  import 'node:http';
4
4
  import 'node:tls';
5
5
  import 'node:stream';
6
+ import 'node:events';
6
7
  import 'ajv';
7
8
 
8
9
  /**
package/dist/index.d.mts CHANGED
@@ -1,14 +1,15 @@
1
1
  import * as node_http from 'node:http';
2
2
  import { Server, IncomingMessage } from 'node:http';
3
- import { EventEmitter } from 'node:events';
4
3
  import WebSocket, { WebSocket as WebSocket$1 } from 'ws';
5
- import { C as ClientOptions, a as ConnectionState, S as SecurityProfile, b as CloseOptions, W as WildcardHandler, c as CallHandler, d as CallOptions, H as HandshakeInfo, e as ServerOptions, A as AuthCallback, L as ListenOptions, E as EventAdapterInterface, V as Validator } from './types-6LVUoXof.mjs';
6
- export { f as AuthAccept, g as ClientEvents, h as HandlerContext, M as MessageType, N as NOREPLY, O as OCPPCall, i as OCPPCallError, j as OCPPCallResult, k as OCPPMessage, l as OCPPProtocol, m as ServerEvents, n as SessionData, T as TLSOptions, o as createValidator } from './types-6LVUoXof.mjs';
4
+ import { O as OCPPProtocol, T as TypedEventEmitter, C as ClientEvents, a as ClientOptions, b as ConnectionState, S as SecurityProfile, c as CloseOptions, A as AllMethodNames, H as HandlerContext, d as OCPPRequestType, e as OCPPResponseType, W as WildcardHandler, f as CallOptions, g as HandshakeInfo, h as ServerEvents, i as ServerOptions, j as AuthCallback, L as ListenOptions, E as EventAdapterInterface, V as Validator } from './types-CpxyZ6AL.mjs';
5
+ export { k as AuthAccept, l as CallHandler, M as MessageType, N as NOREPLY, m as OCPP16Methods, n as OCPP201Methods, o as OCPP21Methods, p as OCPPCall, q as OCPPCallError, r as OCPPCallResult, s as OCPPMessage, t as OCPPMethodMap, u as SessionData, v as TLSOptions, w as createValidator } from './types-CpxyZ6AL.mjs';
7
6
  import { Duplex } from 'node:stream';
8
7
  import 'node:https';
9
8
  import 'node:tls';
9
+ import 'node:events';
10
10
  import 'ajv';
11
11
 
12
+ declare const OCPPClient_base: new () => TypedEventEmitter<ClientEvents>;
12
13
  /**
13
14
  * OCPPClient — A typed WebSocket RPC client for OCPP communication.
14
15
  *
@@ -17,7 +18,7 @@ import 'ajv';
17
18
  * - Profile 2: TLS + Basic Auth
18
19
  * - Profile 3: Mutual TLS (client certificates)
19
20
  */
20
- declare class OCPPClient extends EventEmitter {
21
+ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClient_base {
21
22
  static readonly CONNECTING: 0;
22
23
  static readonly OPEN: 1;
23
24
  static readonly CLOSING: 2;
@@ -55,10 +56,32 @@ declare class OCPPClient extends EventEmitter {
55
56
  reason: string;
56
57
  }>;
57
58
  private _closeInternal;
58
- handle<TParams = unknown, TResult = unknown>(methodOrHandler: string | WildcardHandler, handler?: CallHandler<TParams, TResult>): void;
59
+ /**
60
+ * Register a version-specific handler — `handle("ocpp1.6", "BootNotification", handler)`.
61
+ * This handler is only invoked when the active protocol matches the given version.
62
+ */
63
+ handle<V extends OCPPProtocol, M extends AllMethodNames<V>>(version: V, method: M, handler: (context: HandlerContext<OCPPRequestType<V, M>>) => OCPPResponseType<V, M> | Promise<OCPPResponseType<V, M>>): void;
64
+ /**
65
+ * Register a handler for the client's default protocol — `handle("BootNotification", handler)`.
66
+ * Uses the default protocol type parameter `P`.
67
+ */
68
+ handle<M extends AllMethodNames<P>>(method: M, handler: (context: HandlerContext<OCPPRequestType<P, M>>) => OCPPResponseType<P, M> | Promise<OCPPResponseType<P, M>>): void;
69
+ /** Register a handler for a custom/extension method not in the typed OCPP method maps. */
70
+ handle(method: string, handler: (context: HandlerContext<Record<string, any>>) => any): void;
71
+ /** Register a wildcard handler for all unhandled methods. */
72
+ handle(handler: WildcardHandler): void;
59
73
  removeHandler(method?: string): void;
74
+ removeHandler(version: OCPPProtocol, method: string): void;
60
75
  removeAllHandlers(): void;
61
- call<TResult = unknown>(method: string, params?: unknown, options?: CallOptions): Promise<TResult>;
76
+ /**
77
+ * Call a version-specific typed method — `call("ocpp1.6", "BootNotification", {...})`.
78
+ * Provides full type inference for params and response based on the OCPP version.
79
+ */
80
+ call<V extends OCPPProtocol, M extends AllMethodNames<V>>(version: V, method: M, params: OCPPRequestType<V, M>, options?: CallOptions): Promise<OCPPResponseType<V, M>>;
81
+ /** Call a known typed method using the client's default protocol. */
82
+ call<M extends AllMethodNames<P>>(method: M, params: OCPPRequestType<P, M>, options?: CallOptions): Promise<OCPPResponseType<P, M>>;
83
+ /** Call a known typed method with explicit response type. */
84
+ call<TResult = unknown>(method: string, params?: Record<string, unknown>, options?: CallOptions): Promise<TResult>;
62
85
  private _sendCall;
63
86
  /**
64
87
  * Send a raw string message over the WebSocket (use with caution).
@@ -98,6 +121,7 @@ declare class OCPPServerClient extends OCPPClient {
98
121
  ws: WebSocket$1;
99
122
  handshake: HandshakeInfo;
100
123
  session: Record<string, unknown>;
124
+ protocol?: string;
101
125
  });
102
126
  /**
103
127
  * Session data associated with this client connection.
@@ -114,6 +138,7 @@ declare class OCPPServerClient extends OCPPClient {
114
138
  connect(): Promise<never>;
115
139
  }
116
140
 
141
+ declare const OCPPServer_base: new () => TypedEventEmitter<ServerEvents>;
117
142
  /**
118
143
  * OCPPServer — A typed WebSocket RPC server for OCPP communication.
119
144
  *
@@ -122,7 +147,7 @@ declare class OCPPServerClient extends OCPPClient {
122
147
  * - Profile 2: TLS + Basic Auth (HTTPS server)
123
148
  * - Profile 3: Mutual TLS (HTTPS server with requestCert)
124
149
  */
125
- declare class OCPPServer extends EventEmitter {
150
+ declare class OCPPServer extends OCPPServer_base {
126
151
  private _options;
127
152
  private _authCallback;
128
153
  private _clients;
@@ -265,4 +290,4 @@ declare class InMemoryAdapter implements EventAdapterInterface {
265
290
  disconnect(): Promise<void>;
266
291
  }
267
292
 
268
- export { AuthCallback, CallHandler, CallOptions, ClientOptions, CloseOptions, ConnectionState, EventAdapterInterface, HandshakeInfo, InMemoryAdapter, ListenOptions, OCPPClient, OCPPServer, OCPPServerClient, type RPCError, RPCFormatViolationError, RPCFormationViolationError, RPCFrameworkError, RPCGenericError, RPCInternalError, RPCMessageTypeNotSupportedError, RPCNotImplementedError, RPCNotSupportedError, RPCOccurrenceConstraintViolationError, RPCPropertyConstraintViolationError, RPCProtocolError, RPCSecurityError, RPCTypeConstraintViolationError, SecurityProfile, ServerOptions, TimeoutError, UnexpectedHttpResponse, Validator, WebsocketUpgradeError, WildcardHandler, createRPCError, getErrorPlainObject, getPackageIdent, standardValidators };
293
+ export { AllMethodNames, AuthCallback, CallOptions, ClientEvents, ClientOptions, CloseOptions, ConnectionState, EventAdapterInterface, HandlerContext, HandshakeInfo, InMemoryAdapter, ListenOptions, OCPPClient, OCPPProtocol, OCPPRequestType, OCPPResponseType, OCPPServer, OCPPServerClient, type RPCError, RPCFormatViolationError, RPCFormationViolationError, RPCFrameworkError, RPCGenericError, RPCInternalError, RPCMessageTypeNotSupportedError, RPCNotImplementedError, RPCNotSupportedError, RPCOccurrenceConstraintViolationError, RPCPropertyConstraintViolationError, RPCProtocolError, RPCSecurityError, RPCTypeConstraintViolationError, SecurityProfile, ServerEvents, ServerOptions, TimeoutError, TypedEventEmitter, UnexpectedHttpResponse, Validator, WebsocketUpgradeError, WildcardHandler, createRPCError, getErrorPlainObject, getPackageIdent, standardValidators };
package/dist/index.d.ts CHANGED
@@ -1,14 +1,15 @@
1
1
  import * as node_http from 'node:http';
2
2
  import { Server, IncomingMessage } from 'node:http';
3
- import { EventEmitter } from 'node:events';
4
3
  import WebSocket, { WebSocket as WebSocket$1 } from 'ws';
5
- import { C as ClientOptions, a as ConnectionState, S as SecurityProfile, b as CloseOptions, W as WildcardHandler, c as CallHandler, d as CallOptions, H as HandshakeInfo, e as ServerOptions, A as AuthCallback, L as ListenOptions, E as EventAdapterInterface, V as Validator } from './types-6LVUoXof.js';
6
- export { f as AuthAccept, g as ClientEvents, h as HandlerContext, M as MessageType, N as NOREPLY, O as OCPPCall, i as OCPPCallError, j as OCPPCallResult, k as OCPPMessage, l as OCPPProtocol, m as ServerEvents, n as SessionData, T as TLSOptions, o as createValidator } from './types-6LVUoXof.js';
4
+ import { O as OCPPProtocol, T as TypedEventEmitter, C as ClientEvents, a as ClientOptions, b as ConnectionState, S as SecurityProfile, c as CloseOptions, A as AllMethodNames, H as HandlerContext, d as OCPPRequestType, e as OCPPResponseType, W as WildcardHandler, f as CallOptions, g as HandshakeInfo, h as ServerEvents, i as ServerOptions, j as AuthCallback, L as ListenOptions, E as EventAdapterInterface, V as Validator } from './types-CpxyZ6AL.js';
5
+ export { k as AuthAccept, l as CallHandler, M as MessageType, N as NOREPLY, m as OCPP16Methods, n as OCPP201Methods, o as OCPP21Methods, p as OCPPCall, q as OCPPCallError, r as OCPPCallResult, s as OCPPMessage, t as OCPPMethodMap, u as SessionData, v as TLSOptions, w as createValidator } from './types-CpxyZ6AL.js';
7
6
  import { Duplex } from 'node:stream';
8
7
  import 'node:https';
9
8
  import 'node:tls';
9
+ import 'node:events';
10
10
  import 'ajv';
11
11
 
12
+ declare const OCPPClient_base: new () => TypedEventEmitter<ClientEvents>;
12
13
  /**
13
14
  * OCPPClient — A typed WebSocket RPC client for OCPP communication.
14
15
  *
@@ -17,7 +18,7 @@ import 'ajv';
17
18
  * - Profile 2: TLS + Basic Auth
18
19
  * - Profile 3: Mutual TLS (client certificates)
19
20
  */
20
- declare class OCPPClient extends EventEmitter {
21
+ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClient_base {
21
22
  static readonly CONNECTING: 0;
22
23
  static readonly OPEN: 1;
23
24
  static readonly CLOSING: 2;
@@ -55,10 +56,32 @@ declare class OCPPClient extends EventEmitter {
55
56
  reason: string;
56
57
  }>;
57
58
  private _closeInternal;
58
- handle<TParams = unknown, TResult = unknown>(methodOrHandler: string | WildcardHandler, handler?: CallHandler<TParams, TResult>): void;
59
+ /**
60
+ * Register a version-specific handler — `handle("ocpp1.6", "BootNotification", handler)`.
61
+ * This handler is only invoked when the active protocol matches the given version.
62
+ */
63
+ handle<V extends OCPPProtocol, M extends AllMethodNames<V>>(version: V, method: M, handler: (context: HandlerContext<OCPPRequestType<V, M>>) => OCPPResponseType<V, M> | Promise<OCPPResponseType<V, M>>): void;
64
+ /**
65
+ * Register a handler for the client's default protocol — `handle("BootNotification", handler)`.
66
+ * Uses the default protocol type parameter `P`.
67
+ */
68
+ handle<M extends AllMethodNames<P>>(method: M, handler: (context: HandlerContext<OCPPRequestType<P, M>>) => OCPPResponseType<P, M> | Promise<OCPPResponseType<P, M>>): void;
69
+ /** Register a handler for a custom/extension method not in the typed OCPP method maps. */
70
+ handle(method: string, handler: (context: HandlerContext<Record<string, any>>) => any): void;
71
+ /** Register a wildcard handler for all unhandled methods. */
72
+ handle(handler: WildcardHandler): void;
59
73
  removeHandler(method?: string): void;
74
+ removeHandler(version: OCPPProtocol, method: string): void;
60
75
  removeAllHandlers(): void;
61
- call<TResult = unknown>(method: string, params?: unknown, options?: CallOptions): Promise<TResult>;
76
+ /**
77
+ * Call a version-specific typed method — `call("ocpp1.6", "BootNotification", {...})`.
78
+ * Provides full type inference for params and response based on the OCPP version.
79
+ */
80
+ call<V extends OCPPProtocol, M extends AllMethodNames<V>>(version: V, method: M, params: OCPPRequestType<V, M>, options?: CallOptions): Promise<OCPPResponseType<V, M>>;
81
+ /** Call a known typed method using the client's default protocol. */
82
+ call<M extends AllMethodNames<P>>(method: M, params: OCPPRequestType<P, M>, options?: CallOptions): Promise<OCPPResponseType<P, M>>;
83
+ /** Call a known typed method with explicit response type. */
84
+ call<TResult = unknown>(method: string, params?: Record<string, unknown>, options?: CallOptions): Promise<TResult>;
62
85
  private _sendCall;
63
86
  /**
64
87
  * Send a raw string message over the WebSocket (use with caution).
@@ -98,6 +121,7 @@ declare class OCPPServerClient extends OCPPClient {
98
121
  ws: WebSocket$1;
99
122
  handshake: HandshakeInfo;
100
123
  session: Record<string, unknown>;
124
+ protocol?: string;
101
125
  });
102
126
  /**
103
127
  * Session data associated with this client connection.
@@ -114,6 +138,7 @@ declare class OCPPServerClient extends OCPPClient {
114
138
  connect(): Promise<never>;
115
139
  }
116
140
 
141
+ declare const OCPPServer_base: new () => TypedEventEmitter<ServerEvents>;
117
142
  /**
118
143
  * OCPPServer — A typed WebSocket RPC server for OCPP communication.
119
144
  *
@@ -122,7 +147,7 @@ declare class OCPPServerClient extends OCPPClient {
122
147
  * - Profile 2: TLS + Basic Auth (HTTPS server)
123
148
  * - Profile 3: Mutual TLS (HTTPS server with requestCert)
124
149
  */
125
- declare class OCPPServer extends EventEmitter {
150
+ declare class OCPPServer extends OCPPServer_base {
126
151
  private _options;
127
152
  private _authCallback;
128
153
  private _clients;
@@ -265,4 +290,4 @@ declare class InMemoryAdapter implements EventAdapterInterface {
265
290
  disconnect(): Promise<void>;
266
291
  }
267
292
 
268
- export { AuthCallback, CallHandler, CallOptions, ClientOptions, CloseOptions, ConnectionState, EventAdapterInterface, HandshakeInfo, InMemoryAdapter, ListenOptions, OCPPClient, OCPPServer, OCPPServerClient, type RPCError, RPCFormatViolationError, RPCFormationViolationError, RPCFrameworkError, RPCGenericError, RPCInternalError, RPCMessageTypeNotSupportedError, RPCNotImplementedError, RPCNotSupportedError, RPCOccurrenceConstraintViolationError, RPCPropertyConstraintViolationError, RPCProtocolError, RPCSecurityError, RPCTypeConstraintViolationError, SecurityProfile, ServerOptions, TimeoutError, UnexpectedHttpResponse, Validator, WebsocketUpgradeError, WildcardHandler, createRPCError, getErrorPlainObject, getPackageIdent, standardValidators };
293
+ export { AllMethodNames, AuthCallback, CallOptions, ClientEvents, ClientOptions, CloseOptions, ConnectionState, EventAdapterInterface, HandlerContext, HandshakeInfo, InMemoryAdapter, ListenOptions, OCPPClient, OCPPProtocol, OCPPRequestType, OCPPResponseType, OCPPServer, OCPPServerClient, type RPCError, RPCFormatViolationError, RPCFormationViolationError, RPCFrameworkError, RPCGenericError, RPCInternalError, RPCMessageTypeNotSupportedError, RPCNotImplementedError, RPCNotSupportedError, RPCOccurrenceConstraintViolationError, RPCPropertyConstraintViolationError, RPCProtocolError, RPCSecurityError, RPCTypeConstraintViolationError, SecurityProfile, ServerEvents, ServerOptions, TimeoutError, TypedEventEmitter, UnexpectedHttpResponse, Validator, WebsocketUpgradeError, WildcardHandler, createRPCError, getErrorPlainObject, getPackageIdent, standardValidators };