opcjs-client 0.1.40-alpha → 0.1.41-alpha
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.
- package/README.md +303 -0
- package/dist/index.cjs +672 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +496 -10
- package/dist/index.d.ts +496 -10
- package/dist/index.js +670 -44
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ISecureChannel, RequestHeader, NodeId, EndpointDescription, UserIdentityToken, Configuration, UserTokenTypeEnum, MessageSecurityModeEnum, ILoggerFactory, Encoder, Decoder, ExpandedNodeId, QualifiedName, LocalizedText, NodeClassEnum, UaPrimitive, XmlElement, ExtensionObject, DataValue
|
|
1
|
+
import { ISecureChannel, RequestHeader, NodeId, EndpointDescription, UserIdentityToken, Configuration, UserTokenTypeEnum, DiagnosticInfo, MessageSecurityModeEnum, ILoggerFactory, Encoder, Decoder, ExpandedNodeId, QualifiedName, LocalizedText, NodeClassEnum, UaPrimitive, XmlElement, ExtensionObject, DataValue } from 'opcjs-base';
|
|
2
2
|
|
|
3
3
|
declare abstract class ServiceBase {
|
|
4
4
|
private authToken;
|
|
@@ -14,7 +14,14 @@ declare abstract class ServiceBase {
|
|
|
14
14
|
* @param context - Short description used in the error message (e.g. "ReadRequest").
|
|
15
15
|
*/
|
|
16
16
|
protected checkServiceResult(result: number | undefined, context: string): void;
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Builds a RequestHeader for an outgoing service request.
|
|
19
|
+
*
|
|
20
|
+
* @param returnDiagnostics - Bitmask of diagnostic fields to request from the
|
|
21
|
+
* server (OPC UA Part 4, §7.15). Use {@link ReturnDiagnosticsMask} constants
|
|
22
|
+
* to compose the value. Default `0` = no diagnostics.
|
|
23
|
+
*/
|
|
24
|
+
protected createRequestHeader(returnDiagnostics?: number, preAllocatedHandle?: number): RequestHeader;
|
|
18
25
|
constructor(authToken: NodeId, secureChannel: ISecureChannel);
|
|
19
26
|
}
|
|
20
27
|
|
|
@@ -23,9 +30,16 @@ declare class SessionService extends ServiceBase {
|
|
|
23
30
|
private logger;
|
|
24
31
|
/**
|
|
25
32
|
* Creates a new session on the server (OPC UA Part 4, Section 5.7.2).
|
|
33
|
+
*
|
|
34
|
+
* @param clientCertificate - Optional DER-encoded client certificate to include in
|
|
35
|
+
* the request. Pass `null` (default) for SecurityPolicy None without a cert.
|
|
36
|
+
* When the server rejects a `null`-cert request with a certificate-related status
|
|
37
|
+
* code, the caller should retry with a `Uint8Array` certificate (OPC UA 1.0
|
|
38
|
+
* fallback — see `CertificateRequiredError`).
|
|
26
39
|
* @returns The session ID, authentication token, and selected server endpoint.
|
|
40
|
+
* @throws {CertificateRequiredError} when the server demands a client certificate.
|
|
27
41
|
*/
|
|
28
|
-
createSession(): Promise<{
|
|
42
|
+
createSession(clientCertificate?: Uint8Array | null): Promise<{
|
|
29
43
|
sessionId: number;
|
|
30
44
|
authToken: NodeId;
|
|
31
45
|
endpoint: EndpointDescription;
|
|
@@ -35,6 +49,20 @@ declare class SessionService extends ServiceBase {
|
|
|
35
49
|
* @param identityToken - User identity token (anonymous, username/password, certificate, or issued token).
|
|
36
50
|
*/
|
|
37
51
|
activateSession(identityToken: UserIdentityToken): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Sends a CancelRequest to the server asking it to abandon the pending
|
|
54
|
+
* service request identified by `requestHandle` (OPC UA Part 4, Section 5.7.5).
|
|
55
|
+
*
|
|
56
|
+
* The server makes a best-effort attempt to cancel matching requests.
|
|
57
|
+
* Cancelled requests complete with a status of `BadRequestCancelledByClient`.
|
|
58
|
+
*
|
|
59
|
+
* @param requestHandle - The `requestHeader.requestHandle` value of the pending
|
|
60
|
+
* request to cancel. Pass `0` to attempt to cancel all outstanding requests
|
|
61
|
+
* (server behaviour for handle 0 is implementation-specific).
|
|
62
|
+
* @returns The number of pending requests that were actually cancelled
|
|
63
|
+
* (`CancelResponse.cancelCount`).
|
|
64
|
+
*/
|
|
65
|
+
cancel(requestHandle: number): Promise<number>;
|
|
38
66
|
/**
|
|
39
67
|
* Closes the current session on the server (OPC UA Part 4, Section 5.7.4).
|
|
40
68
|
* @param deleteSubscriptions - When true the server deletes all Subscriptions
|
|
@@ -93,6 +121,20 @@ declare class Session {
|
|
|
93
121
|
getAuthToken(): NodeId;
|
|
94
122
|
getSessionId(): number;
|
|
95
123
|
getEndpoint(): EndpointDescription;
|
|
124
|
+
/**
|
|
125
|
+
* Switches the active user identity for this session by calling ActivateSession with
|
|
126
|
+
* a new identity token (OPC UA Part 4, Section 5.7.3 — Session Client Impersonate
|
|
127
|
+
* conformance unit).
|
|
128
|
+
*
|
|
129
|
+
* The server re-evaluates authorisation for the session under the new identity.
|
|
130
|
+
* All existing Subscriptions and MonitoredItems are preserved; only the security
|
|
131
|
+
* context changes.
|
|
132
|
+
*
|
|
133
|
+
* @param identity - The new user identity to apply to the session.
|
|
134
|
+
* @throws When the server returns a non-Good ServiceResult (e.g. `BadIdentityTokenRejected`
|
|
135
|
+
* or `BadUserAccessDenied`).
|
|
136
|
+
*/
|
|
137
|
+
impersonate(identity: UserIdentity): Promise<void>;
|
|
96
138
|
/**
|
|
97
139
|
* Closes the session on the server (OPC UA Part 4, Section 5.7.4).
|
|
98
140
|
* @param deleteSubscriptions - When true the server deletes all Subscriptions
|
|
@@ -105,7 +147,11 @@ declare class Session {
|
|
|
105
147
|
declare class ReadValueResult {
|
|
106
148
|
value: unknown;
|
|
107
149
|
statusCode: number;
|
|
108
|
-
|
|
150
|
+
/** Diagnostic info returned by the server when `returnDiagnostics` was set in the request options. */
|
|
151
|
+
diagnosticInfo?: DiagnosticInfo | undefined;
|
|
152
|
+
constructor(value: unknown, statusCode: number,
|
|
153
|
+
/** Diagnostic info returned by the server when `returnDiagnostics` was set in the request options. */
|
|
154
|
+
diagnosticInfo?: DiagnosticInfo | undefined);
|
|
109
155
|
}
|
|
110
156
|
|
|
111
157
|
/** Options for creating a subscription. All fields are optional; server will revise requested values. */
|
|
@@ -209,6 +255,20 @@ type SecurityConfiguration = {
|
|
|
209
255
|
* implemented alongside non-None security policies.
|
|
210
256
|
*/
|
|
211
257
|
unknownCertificatePolicy?: UnknownCertificatePolicy;
|
|
258
|
+
/**
|
|
259
|
+
* DER-encoded X.509 ApplicationInstanceCertificate for this client.
|
|
260
|
+
*
|
|
261
|
+
* When set, this certificate is used in a OPC UA 1.0 compatibility fallback:
|
|
262
|
+
* if `CreateSession` with no client certificate is rejected by the server with
|
|
263
|
+
* a certificate-related status code (`BadCertificateInvalid`,
|
|
264
|
+
* `BadSecurityChecksFailed`, or `BadNoValidCertificates`), the `CreateSession`
|
|
265
|
+
* is automatically retried with this certificate in the `clientCertificate`
|
|
266
|
+
* field (OPC UA Part 4, SecurityPolicy None – CreateSession/ActivateSession 1.0
|
|
267
|
+
* optional conformance unit).
|
|
268
|
+
*
|
|
269
|
+
* Without this field the fallback is disabled and the error propagates as-is.
|
|
270
|
+
*/
|
|
271
|
+
applicationInstanceCertificate?: Uint8Array;
|
|
212
272
|
};
|
|
213
273
|
|
|
214
274
|
declare class ConfigurationClient extends Configuration {
|
|
@@ -220,6 +280,26 @@ declare class ConfigurationClient extends Configuration {
|
|
|
220
280
|
* @see SecurityConfiguration
|
|
221
281
|
*/
|
|
222
282
|
securityConfiguration?: SecurityConfiguration;
|
|
283
|
+
/**
|
|
284
|
+
* How long to wait (ms) before attempting a reconnect after a server-shutdown
|
|
285
|
+
* is detected via `ServerStatus/State = Shutdown` or a subscription
|
|
286
|
+
* `StatusChangeNotification` with `BadShutdown` / `BadServerHalted`.
|
|
287
|
+
*
|
|
288
|
+
* Gives the server process time to exit fully before the client tries to
|
|
289
|
+
* re-connect. Defaults to 5 000 ms.
|
|
290
|
+
*/
|
|
291
|
+
shutdownReconnectDelayMs: number;
|
|
292
|
+
/**
|
|
293
|
+
* Minimum reconnect delay in milliseconds used when
|
|
294
|
+
* `Server/ServerStatus/EstimatedReturnTime` is already in the past (the server
|
|
295
|
+
* should already be available again).
|
|
296
|
+
*
|
|
297
|
+
* Also acts as the lower bound for the ERT-derived delay, ensuring the client
|
|
298
|
+
* always waits at least this long before retrying.
|
|
299
|
+
*
|
|
300
|
+
* Defaults to 1 000 ms.
|
|
301
|
+
*/
|
|
302
|
+
minReconnectDelayMs: number;
|
|
223
303
|
static getSimple(name: string, company: string, loggerFactory?: ILoggerFactory): ConfigurationClient;
|
|
224
304
|
constructor(applicationName: string, applicationUri: string, productName: string, productUri: string, encoder: Encoder, decoder: Decoder, loggerFactory: ILoggerFactory);
|
|
225
305
|
}
|
|
@@ -227,7 +307,11 @@ declare class ConfigurationClient extends Configuration {
|
|
|
227
307
|
declare class CallMethodResult {
|
|
228
308
|
values: unknown[];
|
|
229
309
|
statusCode: number;
|
|
230
|
-
|
|
310
|
+
/** Diagnostic info returned by the server when `returnDiagnostics` was set in the request options. */
|
|
311
|
+
diagnosticInfo?: DiagnosticInfo | undefined;
|
|
312
|
+
constructor(values: unknown[], statusCode: number,
|
|
313
|
+
/** Diagnostic info returned by the server when `returnDiagnostics` was set in the request options. */
|
|
314
|
+
diagnosticInfo?: DiagnosticInfo | undefined);
|
|
231
315
|
}
|
|
232
316
|
|
|
233
317
|
declare class BrowseNodeResult {
|
|
@@ -259,6 +343,165 @@ type ScalarCallMethodArgument = UaPrimitive | NodeId | ExpandedNodeId | Qualifie
|
|
|
259
343
|
*/
|
|
260
344
|
type CallMethodArgument = ScalarCallMethodArgument | ScalarCallMethodArgument[];
|
|
261
345
|
|
|
346
|
+
/**
|
|
347
|
+
* Bitmask constants for the `returnDiagnostics` field in the OPC UA RequestHeader
|
|
348
|
+
* (OPC UA Part 4, §7.15 — DiagnosticsMask).
|
|
349
|
+
*
|
|
350
|
+
* Combine values with bitwise OR to request multiple diagnostic fields.
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* ```ts
|
|
354
|
+
* import { ReturnDiagnosticsMask, RequestOptions } from 'opcjs-client'
|
|
355
|
+
*
|
|
356
|
+
* const options: RequestOptions = {
|
|
357
|
+
* returnDiagnostics: ReturnDiagnosticsMask.ServiceLevel | ReturnDiagnosticsMask.OperationLevel,
|
|
358
|
+
* }
|
|
359
|
+
* ```
|
|
360
|
+
*/
|
|
361
|
+
declare const ReturnDiagnosticsMask: {
|
|
362
|
+
/** All service-level diagnostic fields. */
|
|
363
|
+
readonly ServiceLevel: 31;
|
|
364
|
+
/** All operation-level diagnostic fields. */
|
|
365
|
+
readonly OperationLevel: 992;
|
|
366
|
+
/** All diagnostic fields (service level + operation level). */
|
|
367
|
+
readonly All: 1023;
|
|
368
|
+
/** Service-level: index to SymbolicId in the server string table. */
|
|
369
|
+
readonly ServiceSymbolicId: 1;
|
|
370
|
+
/** Service-level: index to LocalizedText in the server string table. */
|
|
371
|
+
readonly ServiceLocalizedText: 2;
|
|
372
|
+
/** Service-level: additional info string. */
|
|
373
|
+
readonly ServiceAdditionalInfo: 4;
|
|
374
|
+
/** Service-level: inner status code. */
|
|
375
|
+
readonly ServiceInnerStatusCode: 8;
|
|
376
|
+
/** Service-level: inner diagnostic info. */
|
|
377
|
+
readonly ServiceInnerDiagnostics: 16;
|
|
378
|
+
/** Operation-level: index to SymbolicId in the server string table. */
|
|
379
|
+
readonly OperationSymbolicId: 32;
|
|
380
|
+
/** Operation-level: index to LocalizedText in the server string table. */
|
|
381
|
+
readonly OperationLocalizedText: 64;
|
|
382
|
+
/** Operation-level: additional info string. */
|
|
383
|
+
readonly OperationAdditionalInfo: 128;
|
|
384
|
+
/** Operation-level: inner status code. */
|
|
385
|
+
readonly OperationInnerStatusCode: 256;
|
|
386
|
+
/** Operation-level: inner diagnostic info. */
|
|
387
|
+
readonly OperationInnerDiagnostics: 512;
|
|
388
|
+
};
|
|
389
|
+
/**
|
|
390
|
+
* Options accepted by all `Client` service calls.
|
|
391
|
+
*
|
|
392
|
+
* Each field is optional; omitting it keeps the existing default behaviour.
|
|
393
|
+
*/
|
|
394
|
+
type RequestOptions = {
|
|
395
|
+
/**
|
|
396
|
+
* Bitmask specifying which diagnostic fields the server should populate in
|
|
397
|
+
* the `diagnosticInfo` fields of the response (OPC UA Part 4, §7.15).
|
|
398
|
+
*
|
|
399
|
+
* Use {@link ReturnDiagnosticsMask} constants to compose the value:
|
|
400
|
+
* ```ts
|
|
401
|
+
* returnDiagnostics: ReturnDiagnosticsMask.All
|
|
402
|
+
* ```
|
|
403
|
+
*
|
|
404
|
+
* Default: `0` — no diagnostics returned.
|
|
405
|
+
*/
|
|
406
|
+
returnDiagnostics?: number;
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Tracks the OPC UA NamespaceArray for a session (OPC UA Part 4, Section 5.7.1 —
|
|
411
|
+
* Session Client Renew NodeIds conformance unit).
|
|
412
|
+
*
|
|
413
|
+
* The NamespaceArray maps namespace indices (used inside NodeIds) to stable namespace
|
|
414
|
+
* URIs. Because the server may assign different indices to the same URI across
|
|
415
|
+
* sessions (e.g. after a server restart), clients that cache NodeIds must remap
|
|
416
|
+
* the namespace index whenever the table changes.
|
|
417
|
+
*
|
|
418
|
+
* Namespace index `0` is always the OPC UA base namespace
|
|
419
|
+
* (`http://opcfoundation.org/UA/`) and is guaranteed never to change by the spec.
|
|
420
|
+
*
|
|
421
|
+
* @example
|
|
422
|
+
* ```ts
|
|
423
|
+
* const oldTable = new NamespaceTable(['http://opcfoundation.org/UA/', 'urn:my-server:model'])
|
|
424
|
+
* // After reconnect the server puts the model namespace at index 2:
|
|
425
|
+
* const newTable = new NamespaceTable(['http://opcfoundation.org/UA/', 'urn:unrelated', 'urn:my-server:model'])
|
|
426
|
+
* const remapped = oldTable.remapNodeId(NodeId.newNumeric(1, 1001), newTable)
|
|
427
|
+
* // remapped === NodeId(2, 1001)
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
declare class NamespaceTable {
|
|
431
|
+
private readonly uris;
|
|
432
|
+
constructor(uris?: string[]);
|
|
433
|
+
/** Returns the namespace URI at the given index, or `undefined` if out of range. */
|
|
434
|
+
getUri(index: number): string | undefined;
|
|
435
|
+
/** Returns the namespace index for the given URI, or `undefined` if not found. */
|
|
436
|
+
getIndex(uri: string): number | undefined;
|
|
437
|
+
/** Returns the full ordered array of namespace URIs. */
|
|
438
|
+
getUris(): readonly string[];
|
|
439
|
+
/** Returns `true` when both tables contain the same URIs in the same order. */
|
|
440
|
+
equals(other: NamespaceTable): boolean;
|
|
441
|
+
/**
|
|
442
|
+
* Remaps the namespace index of `nodeId` from this table to the equivalent
|
|
443
|
+
* index in `newTable` by matching namespace URIs.
|
|
444
|
+
*
|
|
445
|
+
* - Namespace index `0` (OPC UA base namespace) is always returned unchanged.
|
|
446
|
+
* - Returns the **same** `NodeId` instance when the index has not changed.
|
|
447
|
+
* - Returns a **new** `NodeId` instance with the updated index when remapping
|
|
448
|
+
* is required.
|
|
449
|
+
*
|
|
450
|
+
* @throws {Error} When the namespace URI at `nodeId.namespace` is not present
|
|
451
|
+
* in this (old) table or when the URI is not present in `newTable`.
|
|
452
|
+
*/
|
|
453
|
+
remapNodeId(nodeId: NodeId, newTable: NamespaceTable): NodeId;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Result of reading a SelectionListType variable's metadata
|
|
458
|
+
* (OPC UA Part 5, §7.18 — Base Info Selection List conformance unit).
|
|
459
|
+
*
|
|
460
|
+
* Represents the set of permitted values and their human-readable descriptions
|
|
461
|
+
* that the server exposes for a variable with a `SelectionListType` TypeDefinition.
|
|
462
|
+
*
|
|
463
|
+
* @example
|
|
464
|
+
* ```ts
|
|
465
|
+
* const list = await client.getSelectionList(nodeId)
|
|
466
|
+
* if (list) {
|
|
467
|
+
* console.log('Permitted values:', list.selections)
|
|
468
|
+
* list.selectionDescriptions.forEach((desc, i) =>
|
|
469
|
+
* console.log(` [${i}] ${desc.text} →`, list.selections[i])
|
|
470
|
+
* )
|
|
471
|
+
* if (list.restrictToList) {
|
|
472
|
+
* console.log('Value must be one of the listed selections.')
|
|
473
|
+
* }
|
|
474
|
+
* }
|
|
475
|
+
* ```
|
|
476
|
+
*/
|
|
477
|
+
type SelectionList = {
|
|
478
|
+
/** The NodeId of the queried variable. */
|
|
479
|
+
readonly nodeId: NodeId;
|
|
480
|
+
/**
|
|
481
|
+
* Array of permitted values for the variable
|
|
482
|
+
* (SelectionListType.Selections mandatory property, OPC 10000-5 §7.18).
|
|
483
|
+
*
|
|
484
|
+
* The DataType is `BaseDataType`; the concrete type of each element depends on
|
|
485
|
+
* the server configuration.
|
|
486
|
+
*/
|
|
487
|
+
readonly selections: readonly unknown[];
|
|
488
|
+
/**
|
|
489
|
+
* Human-readable description for each permitted value
|
|
490
|
+
* (SelectionListType.SelectionDescriptions optional property, OPC 10000-5 §7.18).
|
|
491
|
+
*
|
|
492
|
+
* Empty when the property is not present on the node.
|
|
493
|
+
* When present, `selectionDescriptions[i]` describes `selections[i]`.
|
|
494
|
+
*/
|
|
495
|
+
readonly selectionDescriptions: readonly LocalizedText[];
|
|
496
|
+
/**
|
|
497
|
+
* When `true`, the variable's value MUST be one of the values in `selections`
|
|
498
|
+
* (SelectionListType.RestrictToList optional property, OPC 10000-5 §7.18).
|
|
499
|
+
*
|
|
500
|
+
* Defaults to `false` when the property is absent on the node.
|
|
501
|
+
*/
|
|
502
|
+
readonly restrictToList: boolean;
|
|
503
|
+
};
|
|
504
|
+
|
|
262
505
|
declare class Client {
|
|
263
506
|
private configuration;
|
|
264
507
|
private identity;
|
|
@@ -274,12 +517,63 @@ declare class Client {
|
|
|
274
517
|
private ws?;
|
|
275
518
|
private sessionHandler?;
|
|
276
519
|
private keepAliveTimer?;
|
|
520
|
+
/** Set to true while a shutdown-triggered reconnect is pending to avoid duplicate attempts. */
|
|
521
|
+
private shutdownReconnectPending;
|
|
522
|
+
/** Most recently read NamespaceArray from the server (Session Client Renew NodeIds). */
|
|
523
|
+
private namespaceTable?;
|
|
524
|
+
/**
|
|
525
|
+
* Called whenever the server's NamespaceArray changes after a session (re-)establishment
|
|
526
|
+
* (OPC UA Part 4, Section 5.7.1 — Session Client Renew NodeIds conformance unit).
|
|
527
|
+
*
|
|
528
|
+
* Use `oldTable.remapNodeId(nodeId, newTable)` to recalculate cached NodeIds.
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* ```ts
|
|
532
|
+
* client.onNamespaceTableChanged = (oldTable, newTable) => {
|
|
533
|
+
* cachedNodeId = oldTable.remapNodeId(cachedNodeId, newTable)
|
|
534
|
+
* }
|
|
535
|
+
* ```
|
|
536
|
+
*/
|
|
537
|
+
onNamespaceTableChanged?: (oldTable: NamespaceTable, newTable: NamespaceTable) => void;
|
|
538
|
+
/**
|
|
539
|
+
* Called when the server sends `EstimatedReturnTime = MinDateTime`, indicating it does not
|
|
540
|
+
* expect to restart (OPC UA Part 5, Section 12.6 — Base Info Client Estimated Return Time
|
|
541
|
+
* conformance unit).
|
|
542
|
+
*
|
|
543
|
+
* When this fires the automatic reconnect is suppressed. The application is responsible for
|
|
544
|
+
* deciding whether to keep the `Client` instance or dispose it.
|
|
545
|
+
*
|
|
546
|
+
* @example
|
|
547
|
+
* ```ts
|
|
548
|
+
* client.onPermanentShutdown = () => {
|
|
549
|
+
* console.warn('Server will not restart — closing client.')
|
|
550
|
+
* }
|
|
551
|
+
* ```
|
|
552
|
+
*/
|
|
553
|
+
onPermanentShutdown?: () => void;
|
|
277
554
|
getSession(): Session;
|
|
278
555
|
/**
|
|
279
556
|
* (Re-)initialises all session-scoped services from the current `this.session`.
|
|
280
557
|
* Called both after the initial `connect()` and after a session refresh.
|
|
281
558
|
*/
|
|
282
559
|
private initServices;
|
|
560
|
+
/**
|
|
561
|
+
* Reads `Server.NamespaceArray` (ns=0, i=2255) and updates the stored
|
|
562
|
+
* `NamespaceTable`. When the table changes compared to the previous read the
|
|
563
|
+
* `onNamespaceTableChanged` callback is fired so the application can remap
|
|
564
|
+
* any cached NodeIds (OPC UA Part 4, Section 5.7.1 — Session Client Renew
|
|
565
|
+
* NodeIds conformance unit).
|
|
566
|
+
*
|
|
567
|
+
* Errors are logged as warnings and do not propagate to the caller.
|
|
568
|
+
*/
|
|
569
|
+
private refreshNamespaceTable;
|
|
570
|
+
/**
|
|
571
|
+
* Returns the most recently read `NamespaceTable` for this session.
|
|
572
|
+
*
|
|
573
|
+
* Available after `connect()` completes (the table is read as part of session
|
|
574
|
+
* establishment). Returns `undefined` before the first successful read.
|
|
575
|
+
*/
|
|
576
|
+
getNamespaceTable(): NamespaceTable | undefined;
|
|
283
577
|
/**
|
|
284
578
|
* Executes `fn` and, if it throws a `SessionInvalidError`, creates a fresh
|
|
285
579
|
* session and retries the operation exactly once.
|
|
@@ -298,9 +592,40 @@ declare class Client {
|
|
|
298
592
|
* Starts a periodic keep-alive timer that reads Server_ServerStatus when no subscription is
|
|
299
593
|
* active. OPC UA Part 4, Section 5.7.1 requires clients to keep the session alive; when no
|
|
300
594
|
* subscription Publish loop is running this is the only mechanism that does so.
|
|
595
|
+
*
|
|
596
|
+
* The keep-alive read also serves as the **Detect Shutdown** mechanism (Session Client Detect
|
|
597
|
+
* Shutdown conformance unit): when the returned `ServerStatusDataType.state` equals
|
|
598
|
+
* `ServerStateEnum.Shutdown` the client schedules a reconnect after
|
|
599
|
+
* `SHUTDOWN_RECONNECT_DELAY_MS` to let the server finish its shutdown sequence.
|
|
301
600
|
*/
|
|
302
601
|
private startKeepAlive;
|
|
303
602
|
private stopKeepAlive;
|
|
603
|
+
/**
|
|
604
|
+
* Called when a server-shutdown announcement is detected — either via the keep-alive read
|
|
605
|
+
* returning `ServerStateEnum.Shutdown` or via a subscription `StatusChangeNotification`
|
|
606
|
+
* with status `BadShutdown` / `BadServerHalted`.
|
|
607
|
+
*
|
|
608
|
+
* Reads `Server/ServerStatus/EstimatedReturnTime` (ns=0, i=2992) to decide how long to
|
|
609
|
+
* wait before reconnecting (Base Info Client Estimated Return Time conformance unit).
|
|
610
|
+
* Falls back to `configuration.shutdownReconnectDelayMs` when the read fails or the
|
|
611
|
+
* attributed service is not yet available. Fires `onPermanentShutdown` and suppresses the
|
|
612
|
+
* reconnect when the server sends `MinDateTime`.
|
|
613
|
+
*
|
|
614
|
+
* Only one reconnect attempt is scheduled at a time; a second detection while one is already
|
|
615
|
+
* pending is silently ignored.
|
|
616
|
+
*/
|
|
617
|
+
private handleServerShutdownDetected;
|
|
618
|
+
/**
|
|
619
|
+
* Reads `Server/ServerStatus/EstimatedReturnTime` (ns=0, i=2992) and returns the reconnect
|
|
620
|
+
* delay in milliseconds (Base Info Client Estimated Return Time — OPC UA Part 5, §12.6):
|
|
621
|
+
*
|
|
622
|
+
* - Valid future `DateTime` → delay = `estimatedReturnTime − now`, clamped to at least
|
|
623
|
+
* `MIN_RECONNECT_DELAY_MS`.
|
|
624
|
+
* - Past `DateTime` (server should already be available) → `MIN_RECONNECT_DELAY_MS`.
|
|
625
|
+
* - OPC UA `MinDateTime` (server will not restart) → `null`.
|
|
626
|
+
* - Unreadable / unavailable → falls back to `configuration.shutdownReconnectDelayMs`.
|
|
627
|
+
*/
|
|
628
|
+
private computeReconnectDelayMs;
|
|
304
629
|
connect(): Promise<void>;
|
|
305
630
|
/**
|
|
306
631
|
* Builds the full WebSocket → TCP → SecureChannel pipeline and returns the
|
|
@@ -342,21 +667,159 @@ declare class Client {
|
|
|
342
667
|
* when the session has already expired on the server side.
|
|
343
668
|
*/
|
|
344
669
|
disconnect(): Promise<void>;
|
|
345
|
-
|
|
670
|
+
/**
|
|
671
|
+
* Reads the Value attribute of one or more Nodes.
|
|
672
|
+
*
|
|
673
|
+
* The returned object is a `Promise` that also exposes `requestHandle` — the
|
|
674
|
+
* OPC UA `requestHandle` assigned to the underlying `ReadRequest`. The handle
|
|
675
|
+
* is available synchronously (before `await`) so it can be passed to
|
|
676
|
+
* `cancel()` to abort the in-flight request.
|
|
677
|
+
*
|
|
678
|
+
* @example
|
|
679
|
+
* ```ts
|
|
680
|
+
* const req = client.read([nodeId])
|
|
681
|
+
* await client.cancel(req.requestHandle) // abort before response
|
|
682
|
+
* const results = await req // ReadValueResult[]
|
|
683
|
+
* ```
|
|
684
|
+
*/
|
|
685
|
+
read(ids: NodeId[], options?: RequestOptions): Promise<ReadValueResult[]> & {
|
|
686
|
+
requestHandle: number;
|
|
687
|
+
};
|
|
346
688
|
/**
|
|
347
689
|
* Method for calling a single method on the server.
|
|
690
|
+
*
|
|
691
|
+
* The returned object is a `Promise` that also exposes `requestHandle` — the
|
|
692
|
+
* OPC UA `requestHandle` assigned to the underlying `CallRequest`. The handle
|
|
693
|
+
* is available synchronously (before `await`) so it can be passed to
|
|
694
|
+
* `cancel()` to abort the in-flight request.
|
|
695
|
+
*
|
|
348
696
|
* @param objectId - NodeId of the Object that owns the method.
|
|
349
697
|
* @param methodId - NodeId of the Method to invoke.
|
|
350
698
|
* @param inputArguments - Input argument Variants (default: empty).
|
|
351
|
-
* @
|
|
699
|
+
* @param options - Request options (e.g. `returnDiagnostics`).
|
|
700
|
+
* @returns A promise resolving to the CallMethodResult, with `requestHandle` available synchronously.
|
|
701
|
+
*/
|
|
702
|
+
callMethod(objectId: NodeId, methodId: NodeId, inputArguments?: CallMethodArgument[], options?: RequestOptions): Promise<CallMethodResult> & {
|
|
703
|
+
requestHandle: number;
|
|
704
|
+
};
|
|
705
|
+
/**
|
|
706
|
+
* Browses the Address Space starting from `nodeId`.
|
|
707
|
+
*
|
|
708
|
+
* The returned object is a `Promise` that also exposes `requestHandle` — the
|
|
709
|
+
* OPC UA `requestHandle` assigned to the initial `BrowseRequest`. The handle
|
|
710
|
+
* is available synchronously (before `await`) so it can be passed to
|
|
711
|
+
* `cancel()` to abort the in-flight request.
|
|
712
|
+
*
|
|
713
|
+
* @param nodeId - Starting node.
|
|
714
|
+
* @param recursive - When true, recursively follows HierarchicalReferences.
|
|
715
|
+
* @param options - Request options (e.g. `returnDiagnostics`).
|
|
716
|
+
* @returns A promise resolving to the list of referenced nodes, with `requestHandle` available synchronously.
|
|
352
717
|
*/
|
|
353
|
-
|
|
354
|
-
|
|
718
|
+
browse(nodeId: NodeId, recursive?: boolean, options?: RequestOptions): Promise<BrowseNodeResult[]> & {
|
|
719
|
+
requestHandle: number;
|
|
720
|
+
};
|
|
355
721
|
private browseRecursive;
|
|
356
722
|
subscribe(ids: NodeId[], callback: (data: {
|
|
357
723
|
id: NodeId;
|
|
358
724
|
value: unknown;
|
|
359
725
|
}[]) => void, options?: SubscriptionOptions): Promise<void>;
|
|
726
|
+
/**
|
|
727
|
+
* Asks the server to cancel a pending service request
|
|
728
|
+
* (OPC UA Part 4, Section 5.7.5 — Session Client Cancel conformance unit).
|
|
729
|
+
*
|
|
730
|
+
* The `requestHandle` uniquely identifies the pending request. It is the value
|
|
731
|
+
* assigned to `RequestHeader.requestHandle` when the request was initially sent.
|
|
732
|
+
* Service calls made through this client automatically assign monotonically
|
|
733
|
+
* increasing handles, so the caller can capture the handle before or after issuing
|
|
734
|
+
* Each method (`read`, `browse`, `callMethod`) returns a `Promise` with a
|
|
735
|
+
* `requestHandle` property that is available synchronously. Pass that handle
|
|
736
|
+
* here to abort the corresponding in-flight request.
|
|
737
|
+
*
|
|
738
|
+
* The server makes a best-effort attempt to cancel the matching request. Cancelled
|
|
739
|
+
* requests complete with status `BadRequestCancelledByClient`. Not all servers
|
|
740
|
+
* guarantee that a request in flight can be cancelled.
|
|
741
|
+
*
|
|
742
|
+
* @param requestHandle - Handle of the pending request to cancel.
|
|
743
|
+
* @returns The number of pending requests the server actually cancelled.
|
|
744
|
+
* @throws If no session is active or the server returns a non-Good status.
|
|
745
|
+
*
|
|
746
|
+
* @example
|
|
747
|
+
* ```ts
|
|
748
|
+
* // Issue a potentially slow operation and immediately cancel it.
|
|
749
|
+
* const req = client.read([nodeId])
|
|
750
|
+
* const cancelled = await client.cancel(req.requestHandle)
|
|
751
|
+
* console.log(`Cancelled ${cancelled} request(s)`)
|
|
752
|
+
* const results = await req // resolves with BadRequestCancelledByClient
|
|
753
|
+
* ```
|
|
754
|
+
*/
|
|
755
|
+
cancel(requestHandle: number): Promise<number>;
|
|
756
|
+
/**
|
|
757
|
+
* Switches the active user identity for the current session by calling ActivateSession
|
|
758
|
+
* with a new identity token (OPC UA Part 4, Section 5.7.3 — Session Client Impersonate
|
|
759
|
+
* conformance unit).
|
|
760
|
+
*
|
|
761
|
+
* The server re-evaluates authorisation under the new identity while keeping all existing
|
|
762
|
+
* Subscriptions and MonitoredItems intact. The new identity is also stored so that any
|
|
763
|
+
* subsequent auto-reconnect or session refresh uses it instead of the original identity.
|
|
764
|
+
*
|
|
765
|
+
* @param identity - The new user identity to apply to the session.
|
|
766
|
+
* @throws {Error} When not connected (call `connect()` first).
|
|
767
|
+
* @throws {Error} When the server rejects the identity (e.g. `BadIdentityTokenRejected`
|
|
768
|
+
* or `BadUserAccessDenied`).
|
|
769
|
+
*
|
|
770
|
+
* @example
|
|
771
|
+
* ```ts
|
|
772
|
+
* await client.connect()
|
|
773
|
+
* // ... work as the original user ...
|
|
774
|
+
* await client.impersonate(UserIdentity.newWithUserName('admin', 'secret'))
|
|
775
|
+
* // ... subsequent calls run under the admin identity ...
|
|
776
|
+
* ```
|
|
777
|
+
*/
|
|
778
|
+
impersonate(identity: UserIdentity): Promise<void>;
|
|
779
|
+
/**
|
|
780
|
+
* Reads the `SelectionListType` metadata for a Variable
|
|
781
|
+
* (OPC UA Part 5, §7.18 — Base Info Client Selection List conformance unit).
|
|
782
|
+
*
|
|
783
|
+
* The client browses the node's `HasProperty` references for `Selections`,
|
|
784
|
+
* `SelectionDescriptions`, and `RestrictToList`, then reads their values in a
|
|
785
|
+
* single batch Read request.
|
|
786
|
+
*
|
|
787
|
+
* Works transparently for instances of `SelectionListType` (ns=0; i=19726) and
|
|
788
|
+
* any of its subtypes, because all subtypes inherit the `Selections` mandatory
|
|
789
|
+
* property.
|
|
790
|
+
*
|
|
791
|
+
* @param nodeId - NodeId of the Variable to inspect.
|
|
792
|
+
* @returns `SelectionList` when the node has a `Selections` property, `null` otherwise.
|
|
793
|
+
* @throws When not connected or if the server returns a non-Good service status.
|
|
794
|
+
*
|
|
795
|
+
* @example
|
|
796
|
+
* ```ts
|
|
797
|
+
* const list = await client.getSelectionList(nodeId)
|
|
798
|
+
* if (list) {
|
|
799
|
+
* list.selectionDescriptions.forEach((desc, i) =>
|
|
800
|
+
* console.log(`[${i}] ${desc.text}:`, list.selections[i])
|
|
801
|
+
* )
|
|
802
|
+
* }
|
|
803
|
+
* ```
|
|
804
|
+
*/
|
|
805
|
+
getSelectionList(nodeId: NodeId): Promise<SelectionList | null>;
|
|
806
|
+
/**
|
|
807
|
+
* Internal implementation of `getSelectionList`. Browses the node's
|
|
808
|
+
* HasProperty references to locate Selections/SelectionDescriptions/RestrictToList,
|
|
809
|
+
* then batch-reads their values.
|
|
810
|
+
*/
|
|
811
|
+
private fetchSelectionList;
|
|
812
|
+
/**
|
|
813
|
+
* The `requestHandle` value that was assigned to the most recently issued
|
|
814
|
+
* service request in this session.
|
|
815
|
+
*
|
|
816
|
+
* @deprecated Prefer accessing `requestHandle` directly on the promise returned
|
|
817
|
+
* by `read()`, `browse()`, or `callMethod()`, which is available synchronously
|
|
818
|
+
* before `await` and avoids relying on shared module state.
|
|
819
|
+
*
|
|
820
|
+
* Returns `0` before any request has been sent.
|
|
821
|
+
*/
|
|
822
|
+
get lastRequestHandle(): number;
|
|
360
823
|
constructor(endpointUrl: string, configuration: ConfigurationClient, identity: UserIdentity);
|
|
361
824
|
}
|
|
362
825
|
|
|
@@ -376,4 +839,27 @@ declare class SessionInvalidError extends Error {
|
|
|
376
839
|
constructor(statusCode: number);
|
|
377
840
|
}
|
|
378
841
|
|
|
379
|
-
|
|
842
|
+
/**
|
|
843
|
+
* Thrown when the server rejects `CreateSession` because no (or an invalid)
|
|
844
|
+
* client certificate was supplied.
|
|
845
|
+
*
|
|
846
|
+
* This signals that the OPC UA 1.0 fallback path should be attempted: retry
|
|
847
|
+
* `CreateSession` with the `applicationInstanceCertificate` from the
|
|
848
|
+
* `SecurityConfiguration`.
|
|
849
|
+
*
|
|
850
|
+
* Relevant OPC UA status codes that trigger this error:
|
|
851
|
+
* - `BadCertificateInvalid` (0x80120000) – null/empty cert was rejected
|
|
852
|
+
* - `BadSecurityChecksFailed` (0x80130000) – security validation failed
|
|
853
|
+
* - `BadNoValidCertificates` (0x80590000) – server found no valid certificate
|
|
854
|
+
*/
|
|
855
|
+
declare class CertificateRequiredError extends Error {
|
|
856
|
+
readonly statusCode: number;
|
|
857
|
+
constructor(statusCode: number);
|
|
858
|
+
}
|
|
859
|
+
/**
|
|
860
|
+
* Status codes that indicate the server requires a client certificate even
|
|
861
|
+
* when SecurityPolicy is None (OPC UA 1.0 servers).
|
|
862
|
+
*/
|
|
863
|
+
declare const CERTIFICATE_REQUIRED_STATUS_CODES: Set<number>;
|
|
864
|
+
|
|
865
|
+
export { BrowseNodeResult, CERTIFICATE_REQUIRED_STATUS_CODES, type CallMethodArgument, CallMethodResult, CertificateRequiredError, Client, ConfigurationClient, NamespaceTable, type RequestOptions, ReturnDiagnosticsMask, SECURITY_POLICY_NONE_URI, type ScalarCallMethodArgument, type SecurityConfiguration, type SelectionList, SessionInvalidError, type SubscriptionOptions, type UnknownCertificatePolicy, UserIdentity };
|