node-opcua-server 2.164.2 → 2.165.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.
@@ -8,28 +8,29 @@ exports.setNextSubscriptionId = setNextSubscriptionId;
8
8
  /**
9
9
  * @module node-opcua-server
10
10
  */
11
- const events_1 = require("events");
12
- const util_1 = require("util");
11
+ const node_events_1 = require("node:events");
12
+ const node_util_1 = require("node:util");
13
13
  const async_1 = __importDefault(require("async"));
14
14
  const chalk_1 = __importDefault(require("chalk"));
15
- const node_opcua_assert_1 = require("node-opcua-assert");
16
- const node_opcua_binary_stream_1 = require("node-opcua-binary-stream");
17
15
  const node_opcua_address_space_1 = require("node-opcua-address-space");
18
16
  const nodeJS_1 = require("node-opcua-address-space/nodeJS");
17
+ const node_opcua_assert_1 = require("node-opcua-assert");
18
+ const node_opcua_binary_stream_1 = require("node-opcua-binary-stream");
19
19
  const node_opcua_common_1 = require("node-opcua-common");
20
- const node_opcua_data_model_1 = require("node-opcua-data-model");
21
- const node_opcua_nodeid_1 = require("node-opcua-nodeid");
22
20
  const node_opcua_constants_1 = require("node-opcua-constants");
21
+ const node_opcua_data_model_1 = require("node-opcua-data-model");
23
22
  const node_opcua_date_time_1 = require("node-opcua-date-time");
24
23
  const node_opcua_debug_1 = require("node-opcua-debug");
24
+ const node_opcua_nodeid_1 = require("node-opcua-nodeid");
25
25
  const node_opcua_nodesets_1 = require("node-opcua-nodesets");
26
26
  const node_opcua_object_registry_1 = require("node-opcua-object-registry");
27
27
  const node_opcua_service_call_1 = require("node-opcua-service-call");
28
- const node_opcua_service_subscription_1 = require("node-opcua-service-subscription");
29
28
  const node_opcua_service_endpoints_1 = require("node-opcua-service-endpoints");
29
+ const node_opcua_service_subscription_1 = require("node-opcua-service-subscription");
30
30
  const node_opcua_status_code_1 = require("node-opcua-status-code");
31
31
  const node_opcua_types_1 = require("node-opcua-types");
32
32
  const node_opcua_variant_1 = require("node-opcua-variant");
33
+ const addressSpace_accessor_1 = require("./addressSpace_accessor");
33
34
  const history_server_capabilities_1 = require("./history_server_capabilities");
34
35
  const monitored_item_1 = require("./monitored_item");
35
36
  const server_capabilities_1 = require("./server_capabilities");
@@ -38,7 +39,6 @@ const server_publish_engine_for_orphan_subscriptions_1 = require("./server_publi
38
39
  const server_session_1 = require("./server_session");
39
40
  const server_subscription_1 = require("./server_subscription");
40
41
  const sessions_compatible_for_transfer_1 = require("./sessions_compatible_for_transfer");
41
- const addressSpace_accessor_1 = require("./addressSpace_accessor");
42
42
  const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
43
43
  const errorLog = (0, node_opcua_debug_1.make_errorLog)(__filename);
44
44
  const warningLog = (0, node_opcua_debug_1.make_warningLog)(__filename);
@@ -50,7 +50,7 @@ async function shutdownAndDisposeAddressSpace() {
50
50
  if (this.addressSpace) {
51
51
  await this.addressSpace.shutdown();
52
52
  this.addressSpace.dispose();
53
- delete this.addressSpace;
53
+ this.addressSpace = null;
54
54
  }
55
55
  }
56
56
  function setSubscriptionDurable(inputArguments, context, callback) {
@@ -143,8 +143,10 @@ function _getSubscription(inputArguments, context) {
143
143
  function resendData(inputArguments, context, callback) {
144
144
  (0, node_opcua_assert_1.assert)(typeof callback === "function");
145
145
  const data = _getSubscription.call(this, inputArguments, context);
146
- if (data.statusCode)
147
- return callback(null, { statusCode: data.statusCode });
146
+ if (data.statusCode) {
147
+ callback(null, { statusCode: data.statusCode });
148
+ return;
149
+ }
148
150
  const { subscription } = data;
149
151
  subscription
150
152
  .resendInitialValues()
@@ -174,8 +176,11 @@ function getMonitoredItemsId(inputArguments, context, callback) {
174
176
  }
175
177
  function __bindVariable(self, nodeId, options) {
176
178
  options = options || {};
179
+ if (!self.addressSpace) {
180
+ return;
181
+ }
177
182
  const variable = self.addressSpace.findNode(nodeId);
178
- if (variable && variable.bindVariable) {
183
+ if (variable?.bindVariable) {
179
184
  variable.bindVariable(options, true);
180
185
  (0, node_opcua_assert_1.assert)(typeof variable.asyncRefresh === "function");
181
186
  (0, node_opcua_assert_1.assert)(typeof variable.refreshFunc === "function");
@@ -201,7 +206,7 @@ function _get_next_subscriptionId() {
201
206
  /**
202
207
  *
203
208
  */
204
- class ServerEngine extends events_1.EventEmitter {
209
+ class ServerEngine extends node_events_1.EventEmitter {
205
210
  static registry = new node_opcua_object_registry_1.ObjectRegistry();
206
211
  isAuditing;
207
212
  serverDiagnosticsSummary;
@@ -257,7 +262,7 @@ class ServerEngine extends events_1.EventEmitter {
257
262
  "http://opcfoundation.org/UA-Profile/Server/StandardEventSubscription",
258
263
  "http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary",
259
264
  "http://opcfoundation.org/UA-Profile/Server/FileAccess",
260
- "http://opcfoundation.org/UA-Profile/Server/StateMachine",
265
+ "http://opcfoundation.org/UA-Profile/Server/StateMachine"
261
266
  // "http://opcfoundation.org/UA-Profile/Transport/wss-uajson",
262
267
  // "http://opcfoundation.org/UA-Profile/Transport/wss-uasc-uabinary"
263
268
  // "http://opcfoundation.org/UA-Profile/Server/DurableSubscription"
@@ -276,8 +281,9 @@ class ServerEngine extends events_1.EventEmitter {
276
281
  // new SignedSoftwareCertificate({})
277
282
  ];
278
283
  // make sure minSupportedSampleRate matches MonitoredItem.minimumSamplingInterval
279
- this.serverCapabilities.__defineGetter__("minSupportedSampleRate", () => {
280
- return options.serverCapabilities?.minSupportedSampleRate || monitored_item_1.MonitoredItem.minimumSamplingInterval;
284
+ Object.defineProperty(this.serverCapabilities, "minSupportedSampleRate", {
285
+ get: () => options.serverCapabilities?.minSupportedSampleRate || monitored_item_1.MonitoredItem.minimumSamplingInterval,
286
+ configurable: true
281
287
  });
282
288
  this.serverConfiguration = options.serverConfiguration;
283
289
  this.historyServerCapabilities = new history_server_capabilities_1.HistoryServerCapabilities(options.historyServerCapabilities);
@@ -287,16 +293,19 @@ class ServerEngine extends events_1.EventEmitter {
287
293
  // note spelling is different for serverDiagnosticsSummary.currentSubscriptionCount
288
294
  // and sessionDiagnostics.currentSubscriptionsCount ( with an s)
289
295
  (0, node_opcua_assert_1.assert)(Object.prototype.hasOwnProperty.call(this.serverDiagnosticsSummary, "currentSubscriptionCount"));
290
- this.serverDiagnosticsSummary.__defineGetter__("currentSubscriptionCount", () => {
291
- // currentSubscriptionCount returns the total number of subscriptions
292
- // that are currently active on all sessions
293
- let counter = 0;
294
- Object.values(this._sessions).forEach((session) => {
295
- counter += session.currentSubscriptionCount;
296
- });
297
- // we also need to add the orphan subscriptions
298
- counter += this._orphanPublishEngine ? this._orphanPublishEngine.subscriptions.length : 0;
299
- return counter;
296
+ Object.defineProperty(this.serverDiagnosticsSummary, "currentSubscriptionCount", {
297
+ get: () => {
298
+ // currentSubscriptionCount returns the total number of subscriptions
299
+ // that are currently active on all sessions
300
+ let counter = 0;
301
+ Object.values(this._sessions).forEach((session) => {
302
+ counter += session.currentSubscriptionCount;
303
+ });
304
+ // we also need to add the orphan subscriptions
305
+ counter += this._orphanPublishEngine ? this._orphanPublishEngine.subscriptions.length : 0;
306
+ return counter;
307
+ },
308
+ configurable: true
300
309
  });
301
310
  this._internalState = "creating";
302
311
  this.setServerState(node_opcua_common_1.ServerState.NoConfiguration);
@@ -304,7 +313,10 @@ class ServerEngine extends events_1.EventEmitter {
304
313
  this._shutdownTasks = [];
305
314
  this._applicationUri = "";
306
315
  if (typeof options.applicationUri === "function") {
307
- this.__defineGetter__("_applicationUri", options.applicationUri);
316
+ Object.defineProperty(this, "_applicationUri", {
317
+ get: options.applicationUri,
318
+ configurable: true
319
+ });
308
320
  }
309
321
  else {
310
322
  this._applicationUri = options.applicationUri || "<unset _applicationUri>";
@@ -312,7 +324,7 @@ class ServerEngine extends events_1.EventEmitter {
312
324
  options.serverDiagnosticsEnabled = Object.prototype.hasOwnProperty.call(options, "serverDiagnosticsEnable")
313
325
  ? options.serverDiagnosticsEnabled
314
326
  : true;
315
- this.serverDiagnosticsEnabled = options.serverDiagnosticsEnabled;
327
+ this.serverDiagnosticsEnabled = options.serverDiagnosticsEnabled || false;
316
328
  }
317
329
  isStarted() {
318
330
  return !!this._serverStatus;
@@ -336,10 +348,10 @@ class ServerEngine extends events_1.EventEmitter {
336
348
  ServerEngine.registry.unregister(this);
337
349
  }
338
350
  get startTime() {
339
- return this._serverStatus.startTime;
351
+ return this._serverStatus.startTime || new Date();
340
352
  }
341
353
  get currentTime() {
342
- return this._serverStatus.currentTime;
354
+ return this._serverStatus.currentTime || new Date();
343
355
  }
344
356
  get buildInfo() {
345
357
  return this._serverStatus.buildInfo;
@@ -469,9 +481,12 @@ class ServerEngine extends events_1.EventEmitter {
469
481
  this._expectedShutdownTime = date;
470
482
  }
471
483
  setShutdownReason(reason) {
484
+ const localizedReason = (0, node_opcua_data_model_1.coerceLocalizedText)(reason);
485
+ if (!localizedReason)
486
+ return;
472
487
  this.addressSpace?.rootFolder.objects.server.serverStatus.shutdownReason.setValueFromSource({
473
488
  dataType: node_opcua_variant_1.DataType.LocalizedText,
474
- value: (0, node_opcua_data_model_1.coerceLocalizedText)(reason)
489
+ value: localizedReason
475
490
  });
476
491
  }
477
492
  /**
@@ -490,7 +505,7 @@ class ServerEngine extends events_1.EventEmitter {
490
505
  * the name of the server
491
506
  */
492
507
  get serverName() {
493
- return this._serverStatus.buildInfo.productName;
508
+ return this._serverStatus.buildInfo?.productName || "";
494
509
  }
495
510
  /**
496
511
  * the server urn
@@ -514,7 +529,69 @@ class ServerEngine extends events_1.EventEmitter {
514
529
  value: serverState
515
530
  });
516
531
  }
532
+ getServerState() {
533
+ return this._serverStatus.state;
534
+ }
535
+ /**
536
+ * Set the `ServerConfiguration.InApplicationSetup` property
537
+ * in the address space.
538
+ *
539
+ * This flag indicates whether the server is currently in
540
+ * its initial application setup phase (e.g. waiting for
541
+ * GDS provisioning).
542
+ */
543
+ setInApplicationSetup(value) {
544
+ const addressSpace = this.addressSpace;
545
+ if (!addressSpace) {
546
+ return;
547
+ }
548
+ const serverConfiguration = addressSpace.rootFolder?.objects?.server?.getChildByName("ServerConfiguration");
549
+ if (!serverConfiguration) {
550
+ return;
551
+ }
552
+ let prop = serverConfiguration.getPropertyByName("InApplicationSetup");
553
+ if (!prop) {
554
+ // InApplicationSetup is ModellingRule_Optional on
555
+ // ServerConfigurationType (i=19308) — instantiate
556
+ // it on the instance on first use.
557
+ const ns = addressSpace.getOwnNamespace();
558
+ prop = ns.addVariable({
559
+ browseName: { name: "InApplicationSetup", namespaceIndex: 0 },
560
+ propertyOf: serverConfiguration,
561
+ typeDefinition: "PropertyType",
562
+ dataType: node_opcua_variant_1.DataType.Boolean,
563
+ minimumSamplingInterval: -1,
564
+ value: { dataType: node_opcua_variant_1.DataType.Boolean, value }
565
+ });
566
+ return;
567
+ }
568
+ prop.setValueFromSource({
569
+ dataType: node_opcua_variant_1.DataType.Boolean,
570
+ value
571
+ });
572
+ }
573
+ /**
574
+ * Read the current value of
575
+ * `ServerConfiguration.InApplicationSetup`.
576
+ *
577
+ * Returns `false` if the property does not exist in
578
+ * the address space.
579
+ */
580
+ getInApplicationSetup() {
581
+ const serverConfiguration = this.addressSpace?.rootFolder?.objects?.server?.getChildByName("ServerConfiguration");
582
+ if (!serverConfiguration) {
583
+ return false;
584
+ }
585
+ const prop = serverConfiguration.getPropertyByName("InApplicationSetup");
586
+ if (!prop) {
587
+ return false;
588
+ }
589
+ return prop.readValue().value.value ?? false;
590
+ }
517
591
  getServerDiagnosticsEnabledFlag() {
592
+ if (!this.addressSpace) {
593
+ return false;
594
+ }
518
595
  const server = this.addressSpace.rootFolder.objects.server;
519
596
  const serverDiagnostics = server.getComponentByName("ServerDiagnostics");
520
597
  if (!serverDiagnostics) {
@@ -623,7 +700,7 @@ class ServerEngine extends events_1.EventEmitter {
623
700
  /* c8 ignore next */
624
701
  if (!(0, node_opcua_variant_1.isValidVariant)(node_opcua_variant_1.VariantArrayType.Scalar, dataType, func())) {
625
702
  errorLog("func", func());
626
- throw new Error("bindStandardScalar : func doesn't provide an value of type " + node_opcua_variant_1.DataType[dataType]);
703
+ throw new Error(`bindStandardScalar : func doesn't provide an value of type ${node_opcua_variant_1.DataType[dataType]}`);
627
704
  }
628
705
  return bindVariableIfPresent(nodeId, {
629
706
  get() {
@@ -636,7 +713,7 @@ class ServerEngine extends events_1.EventEmitter {
636
713
  set: setter_func2
637
714
  });
638
715
  };
639
- const bindStandardArray = (id, variantDataType, dataType, func) => {
716
+ const bindStandardArray = (id, variantDataType, _dataType, func) => {
640
717
  (0, node_opcua_assert_1.assert)(typeof func === "function");
641
718
  (0, node_opcua_assert_1.assert)(variantDataType !== null); // check invalid dataType
642
719
  const nodeId = (0, node_opcua_nodeid_1.makeNodeId)(id);
@@ -658,7 +735,7 @@ class ServerEngine extends events_1.EventEmitter {
658
735
  };
659
736
  bindStandardScalar(node_opcua_constants_1.VariableIds.Server_EstimatedReturnTime, node_opcua_variant_1.DataType.DateTime, () => (0, node_opcua_date_time_1.getMinOPCUADate)());
660
737
  // TimeZoneDataType
661
- const timeZoneDataType = addressSpace.findDataType((0, node_opcua_nodeid_1.resolveNodeId)(node_opcua_constants_1.DataTypeIds.TimeZoneDataType));
738
+ addressSpace.findDataType((0, node_opcua_nodeid_1.resolveNodeId)(node_opcua_constants_1.DataTypeIds.TimeZoneDataType));
662
739
  const timeZone = new node_opcua_types_1.TimeZoneDataType({
663
740
  daylightSavingInOffset: /* boolean*/ false,
664
741
  offset: /* int16 */ 0
@@ -802,7 +879,7 @@ class ServerEngine extends events_1.EventEmitter {
802
879
  (0, node_opcua_assert_1.assert)(operationLimits !== null && typeof operationLimits === "object");
803
880
  const keys = Object.keys(operationLimits);
804
881
  keys.forEach((key) => {
805
- const uid = "Server_ServerCapabilities_OperationLimits_" + upperCaseFirst(key);
882
+ const uid = `Server_ServerCapabilities_OperationLimits_${upperCaseFirst(key)}`;
806
883
  const nodeId = (0, node_opcua_nodeid_1.makeNodeId)(node_opcua_constants_1.VariableIds[uid]);
807
884
  (0, node_opcua_assert_1.assert)(!nodeId.isEmpty());
808
885
  bindStandardScalar(node_opcua_constants_1.VariableIds[uid], node_opcua_variant_1.DataType.UInt32, () => {
@@ -938,7 +1015,7 @@ class ServerEngine extends events_1.EventEmitter {
938
1015
  this.__internal_bindMethod((0, node_opcua_nodeid_1.makeNodeId)(node_opcua_constants_1.MethodIds.Server_RequestServerStateChange), requestServerStateChange.bind(this));
939
1016
  // fix getMonitoredItems.outputArguments arrayDimensions
940
1017
  const fixGetMonitoredItemArgs = () => {
941
- const objects = this.addressSpace.rootFolder?.objects;
1018
+ const objects = this.addressSpace?.rootFolder?.objects;
942
1019
  if (!objects || !objects.server) {
943
1020
  return;
944
1021
  }
@@ -947,6 +1024,9 @@ class ServerEngine extends events_1.EventEmitter {
947
1024
  return;
948
1025
  }
949
1026
  const outputArguments = getMonitoredItemsMethod.outputArguments;
1027
+ if (!outputArguments) {
1028
+ return;
1029
+ }
950
1030
  const dataValue = outputArguments.readValue();
951
1031
  if (!dataValue.value?.value) {
952
1032
  // value is null or undefined , meaning no arguments necessary
@@ -958,6 +1038,9 @@ class ServerEngine extends events_1.EventEmitter {
958
1038
  fixGetMonitoredItemArgs();
959
1039
  const prepareServerDiagnostics = () => {
960
1040
  const addressSpace1 = this.addressSpace;
1041
+ if (!addressSpace1) {
1042
+ return;
1043
+ }
961
1044
  if (!addressSpace1.rootFolder.objects) {
962
1045
  return;
963
1046
  }
@@ -982,13 +1065,15 @@ class ServerEngine extends events_1.EventEmitter {
982
1065
  const samplingIntervalDiagnosticsArray = serverDiagnosticsNode.getComponentByName("SamplingIntervalDiagnosticsArray");
983
1066
  if (samplingIntervalDiagnosticsArray) {
984
1067
  addressSpace.deleteNode(samplingIntervalDiagnosticsArray);
985
- const s = serverDiagnosticsNode.getComponents();
986
1068
  }
987
1069
  const subscriptionDiagnosticsArrayNode = serverDiagnosticsNode.getComponentByName("SubscriptionDiagnosticsArray");
988
1070
  (0, node_opcua_assert_1.assert)(subscriptionDiagnosticsArrayNode.nodeClass === node_opcua_data_model_1.NodeClass.Variable);
989
1071
  (0, node_opcua_address_space_1.bindExtObjArrayNode)(subscriptionDiagnosticsArrayNode, "SubscriptionDiagnosticsType", "subscriptionId");
990
1072
  makeNotReadableIfEnabledFlagIsFalse(subscriptionDiagnosticsArrayNode);
991
1073
  const sessionsDiagnosticsSummary = serverDiagnosticsNode.getComponentByName("SessionsDiagnosticsSummary");
1074
+ if (!sessionsDiagnosticsSummary) {
1075
+ return;
1076
+ }
992
1077
  const sessionDiagnosticsArray = sessionsDiagnosticsSummary.getComponentByName("SessionDiagnosticsArray");
993
1078
  (0, node_opcua_assert_1.assert)(sessionDiagnosticsArray.nodeClass === node_opcua_data_model_1.NodeClass.Variable);
994
1079
  (0, node_opcua_address_space_1.bindExtObjArrayNode)(sessionDiagnosticsArray, "SessionDiagnosticsVariableType", "sessionId");
@@ -1013,7 +1098,7 @@ class ServerEngine extends events_1.EventEmitter {
1013
1098
  // do expansion first
1014
1099
  for (const browseDescription of nodesToBrowse) {
1015
1100
  const nodeId = (0, node_opcua_nodeid_1.resolveNodeId)(browseDescription.nodeId);
1016
- const node = this.addressSpace.findNode(nodeId);
1101
+ const node = this.addressSpace?.findNode(nodeId);
1017
1102
  if (node) {
1018
1103
  if (node.onFirstBrowseAction) {
1019
1104
  try {
@@ -1021,7 +1106,7 @@ class ServerEngine extends events_1.EventEmitter {
1021
1106
  node.onFirstBrowseAction = undefined;
1022
1107
  }
1023
1108
  catch (err) {
1024
- if (util_1.types.isNativeError(err)) {
1109
+ if (node_util_1.types.isNativeError(err)) {
1025
1110
  errorLog("onFirstBrowseAction method has failed", err.message);
1026
1111
  }
1027
1112
  errorLog(err);
@@ -1033,18 +1118,33 @@ class ServerEngine extends events_1.EventEmitter {
1033
1118
  return await this.browse(context, nodesToBrowse);
1034
1119
  }
1035
1120
  async browse(context, nodesToBrowse) {
1121
+ if (!this.addressSpaceAccessor) {
1122
+ throw new Error("addressSpaceAccessor is not available");
1123
+ }
1036
1124
  return this.addressSpaceAccessor.browse(context, nodesToBrowse);
1037
1125
  }
1038
1126
  async read(context, readRequest) {
1127
+ if (!this.addressSpaceAccessor) {
1128
+ throw new Error("addressSpaceAccessor is not available");
1129
+ }
1039
1130
  return this.addressSpaceAccessor.read(context, readRequest);
1040
1131
  }
1041
1132
  async write(context, nodesToWrite) {
1133
+ if (!this.addressSpaceAccessor) {
1134
+ throw new Error("addressSpaceAccessor is not available");
1135
+ }
1042
1136
  return await this.addressSpaceAccessor.write(context, nodesToWrite);
1043
1137
  }
1044
1138
  async call(context, methodsToCall) {
1139
+ if (!this.addressSpaceAccessor) {
1140
+ throw new Error("addressSpaceAccessor is not available");
1141
+ }
1045
1142
  return await this.addressSpaceAccessor.call(context, methodsToCall);
1046
1143
  }
1047
1144
  async historyRead(context, historyReadRequest) {
1145
+ if (!this.addressSpaceAccessor) {
1146
+ throw new Error("addressSpaceAccessor is not available");
1147
+ }
1048
1148
  return this.addressSpaceAccessor.historyRead(context, historyReadRequest);
1049
1149
  }
1050
1150
  getOldestInactiveSession() {
@@ -1077,19 +1177,19 @@ class ServerEngine extends events_1.EventEmitter {
1077
1177
  this.clientDescription = options.clientDescription || new node_opcua_service_endpoints_1.ApplicationDescription({});
1078
1178
  const sessionTimeout = options.sessionTimeout || 1000;
1079
1179
  (0, node_opcua_assert_1.assert)(typeof sessionTimeout === "number");
1080
- const session = new server_session_1.ServerSession(this, options.server.userManager, sessionTimeout);
1180
+ const session = new server_session_1.ServerSession(this, options.server.userManager || {}, sessionTimeout);
1081
1181
  debugLog("createSession :sessionTimeout = ", session.sessionTimeout);
1082
1182
  const key = session.authenticationToken.toString();
1083
1183
  this._sessions[key] = session;
1084
1184
  // see spec OPC Unified Architecture, Part 2 page 26 Release 1.02
1085
1185
  // TODO : When a Session is created, the Server adds an entry for the Client
1086
1186
  // in its SessionDiagnosticsArray Variable
1087
- session.on("new_subscription", (subscription) => {
1187
+ session.on("new_subscription", (_subscription) => {
1088
1188
  this.serverDiagnosticsSummary.cumulatedSubscriptionCount += 1;
1089
1189
  // add the subscription diagnostics in our subscriptions diagnostics array
1090
1190
  // note currentSubscriptionCount is handled directly with a special getter
1091
1191
  });
1092
- session.on("subscription_terminated", (subscription) => {
1192
+ session.on("subscription_terminated", (_subscription) => {
1093
1193
  // remove the subscription diagnostics in our subscriptions diagnostics array
1094
1194
  // note currentSubscriptionCount is handled directly with a special getter
1095
1195
  });
@@ -1138,7 +1238,7 @@ class ServerEngine extends events_1.EventEmitter {
1138
1238
  const session = this.getSession(authenticationToken);
1139
1239
  // c8 ignore next
1140
1240
  if (!session) {
1141
- throw new Error("cannot find session with this authenticationToken " + authenticationToken.toString());
1241
+ throw new Error(`cannot find session with this authenticationToken ${authenticationToken.toString()}`);
1142
1242
  }
1143
1243
  if (!deleteSubscriptions) {
1144
1244
  // Live Subscriptions will not be deleted, but transferred to the orphanPublishEngine
@@ -1161,7 +1261,7 @@ class ServerEngine extends events_1.EventEmitter {
1161
1261
  }
1162
1262
  findSubscription(subscriptionId) {
1163
1263
  const subscriptions = [];
1164
- Object.values(this._sessions).map((session) => {
1264
+ Object.values(this._sessions).forEach((session) => {
1165
1265
  if (subscriptions.length) {
1166
1266
  return;
1167
1267
  }
@@ -1230,7 +1330,6 @@ class ServerEngine extends events_1.EventEmitter {
1230
1330
  subscription.subscriptionDiagnostics.transferredToAltClientCount++;
1231
1331
  // The number of times the subscription has been transferred to an alternate session for the same client.
1232
1332
  subscription.subscriptionDiagnostics.transferredToSameClientCount++;
1233
- const nbSubscriptionBefore = session.publishEngine.subscriptionCount;
1234
1333
  if (subscription.$session) {
1235
1334
  subscription.$session._unexposeSubscriptionDiagnostics(subscription);
1236
1335
  }
@@ -1277,6 +1376,9 @@ class ServerEngine extends events_1.EventEmitter {
1277
1376
  return browsePathResults;
1278
1377
  }
1279
1378
  async translateBrowsePath(browsePath) {
1379
+ if (!this.addressSpace) {
1380
+ throw new Error("addressSpace is not available");
1381
+ }
1280
1382
  return this.addressSpace.browsePath(browsePath);
1281
1383
  }
1282
1384
  /**
@@ -1308,7 +1410,7 @@ class ServerEngine extends events_1.EventEmitter {
1308
1410
  continue;
1309
1411
  }
1310
1412
  // ... and that are valid object and instances of Variables ...
1311
- const uaNode = this.addressSpace.findNode(nodeToRefresh.nodeId);
1413
+ const uaNode = this.addressSpace?.findNode(nodeToRefresh.nodeId);
1312
1414
  if (!uaNode || !(uaNode.nodeClass === node_opcua_data_model_1.NodeClass.Variable)) {
1313
1415
  continue;
1314
1416
  }
@@ -1325,7 +1427,8 @@ class ServerEngine extends events_1.EventEmitter {
1325
1427
  const uaVariableArray = Object.values(nodeMap);
1326
1428
  if (uaVariableArray.length === 0) {
1327
1429
  // nothing to do
1328
- return callback(null, []);
1430
+ callback(null, []);
1431
+ return;
1329
1432
  }
1330
1433
  // perform all asyncRefresh in parallel
1331
1434
  async_1.default.map(uaVariableArray, (uaVariable, inner_callback) => {
@@ -1363,7 +1466,6 @@ class ServerEngine extends events_1.EventEmitter {
1363
1466
  const subscriptionDiagnostics = subscription.subscriptionDiagnostics;
1364
1467
  (0, node_opcua_assert_1.assert)(subscriptionDiagnostics instanceof node_opcua_common_1.SubscriptionDiagnosticsDataType);
1365
1468
  if (subscriptionDiagnostics && serverSubscriptionDiagnosticsArray) {
1366
- const node = serverSubscriptionDiagnosticsArray[subscription.id];
1367
1469
  (0, node_opcua_address_space_1.removeElement)(serverSubscriptionDiagnosticsArray, (a) => a.subscriptionId === subscription.id);
1368
1470
  /*assert(
1369
1471
  !(subscriptionDiagnosticsArray as any)[subscription.id],
@@ -1418,15 +1520,15 @@ class ServerEngine extends events_1.EventEmitter {
1418
1520
  __internal_bindMethod(nodeId, func) {
1419
1521
  (0, node_opcua_assert_1.assert)(typeof func === "function");
1420
1522
  (0, node_opcua_assert_1.assert)(nodeId instanceof node_opcua_nodeid_1.NodeId);
1421
- const methodNode = this.addressSpace.findNode(nodeId);
1523
+ const methodNode = this.addressSpace?.findNode(nodeId);
1422
1524
  if (!methodNode) {
1423
1525
  return;
1424
1526
  }
1425
- if (methodNode && methodNode.bindMethod) {
1527
+ if (methodNode?.bindMethod) {
1426
1528
  methodNode.bindMethod(func);
1427
1529
  }
1428
- /* c8 ignore next */
1429
1530
  else {
1531
+ /* c8 ignore next */
1430
1532
  warningLog(chalk_1.default.yellow("WARNING: cannot bind a method with id ") +
1431
1533
  chalk_1.default.cyan(nodeId.toString()) +
1432
1534
  chalk_1.default.yellow(". please check your nodeset.xml file or add this node programmatically"));
@@ -1441,8 +1543,7 @@ class ServerEngine extends events_1.EventEmitter {
1441
1543
  }
1442
1544
  const subscriptionDiagnosticsType = this.addressSpace.findVariableType("SubscriptionDiagnosticsType");
1443
1545
  if (!subscriptionDiagnosticsType) {
1444
- doDebug &&
1445
- debugLog("ServerEngine#_getServerSubscriptionDiagnosticsArray " + ": cannot find SubscriptionDiagnosticsType");
1546
+ doDebug && debugLog(`ServerEngine#_getServerSubscriptionDiagnosticsArray : cannot find SubscriptionDiagnosticsType`);
1446
1547
  }
1447
1548
  // SubscriptionDiagnosticsArray = i=2290
1448
1549
  const subscriptionDiagnosticsArrayNode = this.addressSpace.findNode((0, node_opcua_nodeid_1.makeNodeId)(node_opcua_constants_1.VariableIds.Server_ServerDiagnostics_SubscriptionDiagnosticsArray));