node-opcua-address-space 2.168.0 → 2.170.1
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/dist/source/loader/namespace_post_step.js +25 -17
- package/dist/source/loader/namespace_post_step.js.map +1 -1
- package/dist/source/session_context.d.ts +3 -1
- package/dist/source/session_context.js +26 -1
- package/dist/source/session_context.js.map +1 -1
- package/dist/source/ua_interface.d.ts +2 -3
- package/dist/source/ua_interface.js +10 -33
- package/dist/source/ua_interface.js.map +1 -1
- package/dist/src/_instantiate_helpers.d.ts +1 -1
- package/dist/src/_instantiate_helpers.js +32 -9
- package/dist/src/_instantiate_helpers.js.map +1 -1
- package/dist/src/_mandatory_child_or_requested_optional_filter.js +3 -3
- package/dist/src/_mandatory_child_or_requested_optional_filter.js.map +1 -1
- package/dist/src/address_space.d.ts +15 -12
- package/dist/src/address_space.js +63 -64
- package/dist/src/address_space.js.map +1 -1
- package/dist/src/alarms_and_conditions/condition_snapshot_impl.js +1 -1
- package/dist/src/alarms_and_conditions/condition_snapshot_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_condition_impl.js +1 -1
- package/dist/src/alarms_and_conditions/ua_condition_impl.js.map +1 -1
- package/dist/src/base_node_impl.d.ts +1 -0
- package/dist/src/base_node_impl.js +11 -0
- package/dist/src/base_node_impl.js.map +1 -1
- package/dist/src/base_node_private.d.ts +10 -7
- package/dist/src/base_node_private.js +74 -50
- package/dist/src/base_node_private.js.map +1 -1
- package/dist/src/check_value_rank_compatibility.js +1 -1
- package/dist/src/check_value_rank_compatibility.js.map +1 -1
- package/dist/src/event_data.d.ts +8 -21
- package/dist/src/event_data.js +24 -19
- package/dist/src/event_data.js.map +1 -1
- package/dist/src/namespace_impl.d.ts +2 -0
- package/dist/src/namespace_impl.js +13 -0
- package/dist/src/namespace_impl.js.map +1 -1
- package/dist/src/ua_method_impl.d.ts +11 -9
- package/dist/src/ua_method_impl.js +24 -27
- package/dist/src/ua_method_impl.js.map +1 -1
- package/dist/src/ua_object_impl.d.ts +6 -5
- package/dist/src/ua_object_impl.js +30 -4
- package/dist/src/ua_object_impl.js.map +1 -1
- package/dist/src/ua_object_type_impl.js +2 -2
- package/dist/src/ua_object_type_impl.js.map +1 -1
- package/dist/src/ua_variable_impl.d.ts +1 -0
- package/dist/src/ua_variable_impl.js +79 -1
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/dist/tsconfig_base.tsbuildinfo +1 -1
- package/distHelpers/get_address_space_fixture.js +14 -14
- package/distHelpers/get_address_space_fixture.js.map +1 -1
- package/distHelpers/index.d.ts +2 -2
- package/distHelpers/index.js +2 -2
- package/distHelpers/index.js.map +1 -1
- package/package.json +34 -34
- package/source/loader/namespace_post_step.ts +28 -19
- package/source/session_context.ts +30 -1
- package/source/ua_interface.ts +24 -38
- package/src/_instantiate_helpers.ts +67 -24
- package/src/_mandatory_child_or_requested_optional_filter.ts +5 -5
- package/src/address_space.ts +127 -124
- package/src/alarms_and_conditions/condition_snapshot_impl.ts +3 -3
- package/src/alarms_and_conditions/ua_condition_impl.ts +1 -1
- package/src/base_node_impl.ts +13 -0
- package/src/base_node_private.ts +163 -139
- package/src/check_value_rank_compatibility.ts +1 -1
- package/src/event_data.ts +57 -54
- package/src/namespace_impl.ts +16 -0
- package/src/ua_method_impl.ts +43 -50
- package/src/ua_object_impl.ts +51 -22
- package/src/ua_object_type_impl.ts +3 -3
- package/src/ua_variable_impl.ts +79 -2
package/src/address_space.ts
CHANGED
|
@@ -2,21 +2,41 @@
|
|
|
2
2
|
* @module node-opcua-address-space
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { randomBytes } from "crypto";
|
|
5
|
+
import { randomBytes } from "node:crypto";
|
|
6
6
|
import chalk from "chalk";
|
|
7
|
-
|
|
7
|
+
import type {
|
|
8
|
+
AddReferenceOpts,
|
|
9
|
+
BaseNode,
|
|
10
|
+
IEventData,
|
|
11
|
+
IHistoricalDataNodeOptions,
|
|
12
|
+
ISessionContext,
|
|
13
|
+
MethodCallInterceptor,
|
|
14
|
+
RaiseEventData,
|
|
15
|
+
ShutdownTask,
|
|
16
|
+
UADataType,
|
|
17
|
+
UAEventType,
|
|
18
|
+
UAMethod,
|
|
19
|
+
UAObject,
|
|
20
|
+
UAObjectType,
|
|
21
|
+
UAReference,
|
|
22
|
+
UAReferenceType,
|
|
23
|
+
UAVariable,
|
|
24
|
+
UAVariableType,
|
|
25
|
+
UAView
|
|
26
|
+
} from "node-opcua-address-space-base";
|
|
8
27
|
import { assert } from "node-opcua-assert";
|
|
9
|
-
import { ExtraDataTypeManager } from "node-opcua-client-dynamic-extension-object";
|
|
28
|
+
import type { ExtraDataTypeManager } from "node-opcua-client-dynamic-extension-object";
|
|
10
29
|
import { DataTypeIds, VariableTypeIds } from "node-opcua-constants";
|
|
11
30
|
import { BrowseDirection, NodeClass, QualifiedName } from "node-opcua-data-model";
|
|
12
|
-
import {
|
|
31
|
+
import { make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
|
|
32
|
+
import type { ExtensionObject } from "node-opcua-extension-object";
|
|
13
33
|
import {
|
|
14
34
|
coerceExpandedNodeId,
|
|
15
35
|
coerceNodeId,
|
|
16
|
-
INodeId,
|
|
36
|
+
type INodeId,
|
|
17
37
|
makeNodeId,
|
|
18
38
|
NodeId,
|
|
19
|
-
NodeIdLike,
|
|
39
|
+
type NodeIdLike,
|
|
20
40
|
NodeIdType,
|
|
21
41
|
resolveNodeId,
|
|
22
42
|
sameNodeId
|
|
@@ -24,61 +44,39 @@ import {
|
|
|
24
44
|
import { ObjectRegistry } from "node-opcua-object-registry";
|
|
25
45
|
import { BrowseResult } from "node-opcua-service-browse";
|
|
26
46
|
import { StatusCodes } from "node-opcua-status-code";
|
|
27
|
-
import {
|
|
47
|
+
import type {
|
|
28
48
|
BrowseDescription,
|
|
29
|
-
BrowsePath,
|
|
30
|
-
BrowsePathResult,
|
|
31
49
|
BrowsePathTargetOptions,
|
|
32
50
|
BrowseResultOptions,
|
|
33
51
|
ModelChangeStructureDataType,
|
|
34
52
|
RelativePathElement
|
|
35
53
|
} from "node-opcua-types";
|
|
36
|
-
import { isNullOrUndefined } from "node-opcua-utils";
|
|
37
|
-
import { lowerFirstLetter } from "node-opcua-utils";
|
|
38
|
-
import { DataType, Variant, VariantArrayType, VariantOptions, VariantT } from "node-opcua-variant";
|
|
39
54
|
import {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
IHistoricalDataNodeOptions,
|
|
46
|
-
UAVariable,
|
|
47
|
-
UADataType,
|
|
48
|
-
UAObjectType,
|
|
49
|
-
BaseNode,
|
|
50
|
-
UAMethod,
|
|
51
|
-
UAVariableType,
|
|
52
|
-
UAReferenceType,
|
|
53
|
-
UAObject,
|
|
54
|
-
UAView,
|
|
55
|
-
IAddressSpace,
|
|
56
|
-
ShutdownTask,
|
|
57
|
-
RaiseEventData,
|
|
58
|
-
UAVariableT,
|
|
59
|
-
MethodCallInterceptor
|
|
60
|
-
} from "node-opcua-address-space-base";
|
|
61
|
-
import { make_debugLog, make_warningLog, make_errorLog } from "node-opcua-debug";
|
|
62
|
-
|
|
55
|
+
BrowsePath,
|
|
56
|
+
BrowsePathResult,
|
|
57
|
+
} from "node-opcua-types";
|
|
58
|
+
import { isNullOrUndefined, lowerFirstLetter } from "node-opcua-utils";
|
|
59
|
+
import { DataType, Variant, VariantArrayType, type VariantOptions, type VariantT } from "node-opcua-variant";
|
|
63
60
|
import { adjustBrowseDirection } from "../source/helpers/adjust_browse_direction";
|
|
64
|
-
import {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
import {
|
|
61
|
+
import type {
|
|
62
|
+
ExtensionObjectConstructorFuncWithSchema
|
|
63
|
+
} from "../source/interfaces/extension_object_constructor";
|
|
64
|
+
import type { UARootFolder } from "../source/ua_root_folder";
|
|
65
|
+
import type { AddressSpacePrivate } from "./address_space_private";
|
|
68
66
|
import { UAAcknowledgeableConditionImpl, UAConditionImpl } from "./alarms_and_conditions";
|
|
67
|
+
import { BaseNodeImpl } from "./base_node_impl";
|
|
69
68
|
import { EventData } from "./event_data";
|
|
70
|
-
import {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
import {
|
|
69
|
+
import {
|
|
70
|
+
AddressSpace_installHistoricalDataNode
|
|
71
|
+
} from "./historical_access/address_space_historical_data_node";
|
|
72
|
+
import { isNonEmptyQualifiedName, NamespaceImpl } from "./namespace_impl";
|
|
73
|
+
import type { NamespacePrivate } from "./namespace_private";
|
|
74
|
+
import { ReferenceImpl } from "./reference_impl";
|
|
74
75
|
import { UADataTypeImpl } from "./ua_data_type_impl";
|
|
75
|
-
import { UAObjectTypeImpl } from "./ua_object_type_impl";
|
|
76
76
|
import { UAObjectImpl } from "./ua_object_impl";
|
|
77
|
-
import {
|
|
78
|
-
import { UAVariableImpl } from "./ua_variable_impl";
|
|
77
|
+
import { UAObjectTypeImpl } from "./ua_object_type_impl";
|
|
79
78
|
import { UAReferenceTypeImpl } from "./ua_reference_type_impl";
|
|
80
|
-
import {
|
|
81
|
-
import { resolve } from "path";
|
|
79
|
+
import type { UAVariableImpl } from "./ua_variable_impl";
|
|
82
80
|
|
|
83
81
|
const doDebug = false;
|
|
84
82
|
const errorLog = make_errorLog(__filename);
|
|
@@ -92,7 +90,7 @@ const regexNumberColumnString = /^([0-9]+):(.*)/;
|
|
|
92
90
|
const enumerationTypeNodeId = coerceNodeId(DataTypeIds.Enumeration);
|
|
93
91
|
/**
|
|
94
92
|
* Extracts the namespace and browse name as a string from the given input.
|
|
95
|
-
*
|
|
93
|
+
*
|
|
96
94
|
* @param addressSpace The address space instance.
|
|
97
95
|
* @param browseNameOrNodeId A NodeIdLike, QualifiedName, or string representing the browse name or node id.
|
|
98
96
|
* @param namespaceIndex Optional namespace index.
|
|
@@ -105,15 +103,19 @@ function _extract_namespace_and_browse_name_as_string(
|
|
|
105
103
|
): [NamespacePrivate, string] {
|
|
106
104
|
assert(!namespaceIndex || namespaceIndex >= 0);
|
|
107
105
|
|
|
108
|
-
let result;
|
|
106
|
+
let result: [NamespacePrivate, string] | undefined;
|
|
109
107
|
|
|
110
108
|
if (namespaceIndex !== undefined && namespaceIndex > 0) {
|
|
111
109
|
assert(typeof browseNameOrNodeId === "string", "expecting a string when namespaceIndex is specified");
|
|
112
|
-
result = [addressSpace.getNamespace(namespaceIndex), browseNameOrNodeId];
|
|
110
|
+
result = [addressSpace.getNamespace(namespaceIndex), browseNameOrNodeId.toString()];
|
|
113
111
|
} else if (typeof browseNameOrNodeId === "string") {
|
|
114
112
|
// we may have a string like "ns=1;i=1234" or "ns=1:MyBrowseName"
|
|
115
113
|
if (isNodeIdString(browseNameOrNodeId)) {
|
|
116
|
-
return _extract_namespace_and_browse_name_as_string(
|
|
114
|
+
return _extract_namespace_and_browse_name_as_string(
|
|
115
|
+
addressSpace,
|
|
116
|
+
addressSpace.resolveNodeId(browseNameOrNodeId),
|
|
117
|
+
namespaceIndex
|
|
118
|
+
);
|
|
117
119
|
}
|
|
118
120
|
// we must have a BrowseName string
|
|
119
121
|
if (browseNameOrNodeId.indexOf(":") >= 0) {
|
|
@@ -124,7 +126,7 @@ function _extract_namespace_and_browse_name_as_string(
|
|
|
124
126
|
result = [addressSpace.getNamespace(namespaceIndex || 0), browseNameOrNodeId];
|
|
125
127
|
} else if (browseNameOrNodeId instanceof QualifiedName) {
|
|
126
128
|
namespaceIndex = browseNameOrNodeId.namespaceIndex;
|
|
127
|
-
result = [addressSpace.getNamespace(namespaceIndex), browseNameOrNodeId.name];
|
|
129
|
+
result = [addressSpace.getNamespace(namespaceIndex), browseNameOrNodeId.name || ""];
|
|
128
130
|
} else if (typeof browseNameOrNodeId === "number") {
|
|
129
131
|
result = [addressSpace.getDefaultNamespace(), DataType[browseNameOrNodeId]];
|
|
130
132
|
} else if (browseNameOrNodeId instanceof NodeId) {
|
|
@@ -201,6 +203,20 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
201
203
|
this.registerNamespace("http://opcfoundation.org/UA/");
|
|
202
204
|
AddressSpace.registry.register(this);
|
|
203
205
|
}
|
|
206
|
+
|
|
207
|
+
public toJSON(): Record<string, string | number | undefined> {
|
|
208
|
+
return {
|
|
209
|
+
namespaces: this._namespaceArray.length
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
public toString(): string {
|
|
214
|
+
return `AddressSpace({ namespaces: ${this._namespaceArray.length} })`;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
public [Symbol.for("nodejs.util.inspect.custom")](): string {
|
|
218
|
+
return this.toString();
|
|
219
|
+
}
|
|
204
220
|
/**
|
|
205
221
|
* @internal
|
|
206
222
|
*/
|
|
@@ -266,7 +282,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
266
282
|
/**
|
|
267
283
|
*
|
|
268
284
|
* register a new namespace,
|
|
269
|
-
* it is OK to call registerNamespace even if namespace has already been registered;
|
|
285
|
+
* it is OK to call registerNamespace even if namespace has already been registered;
|
|
270
286
|
* in this case the registerNamespace has no effect and returns the existing namespace.
|
|
271
287
|
*
|
|
272
288
|
* @param namespaceUri {string}
|
|
@@ -478,7 +494,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
478
494
|
const resolvedDataType = this.resolveNodeId(dataTypeNode);
|
|
479
495
|
/* c8 ignore next */
|
|
480
496
|
if (!resolvedDataType) {
|
|
481
|
-
throw new Error(
|
|
497
|
+
throw new Error(`Cannot resolve ${_orig_dataTypeNode.toString()}`);
|
|
482
498
|
}
|
|
483
499
|
dataTypeNode = resolvedDataType;
|
|
484
500
|
}
|
|
@@ -487,7 +503,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
487
503
|
dataTypeNode = this.findDataType(dataTypeNode)!;
|
|
488
504
|
/* c8 ignore next */
|
|
489
505
|
if (!dataTypeNode) {
|
|
490
|
-
throw Error(
|
|
506
|
+
throw Error(`cannot find dataTypeNode ${_orig_dataTypeNode.toString()}`);
|
|
491
507
|
}
|
|
492
508
|
}
|
|
493
509
|
/* c8 ignore next */
|
|
@@ -500,7 +516,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
500
516
|
);
|
|
501
517
|
}
|
|
502
518
|
|
|
503
|
-
if (sameNodeId(enumerationTypeNodeId, dataTypeNode
|
|
519
|
+
if (sameNodeId(enumerationTypeNodeId, dataTypeNode?.nodeId)) {
|
|
504
520
|
return DataType.Int32;
|
|
505
521
|
}
|
|
506
522
|
const n = dataTypeNode.nodeId as INodeId;
|
|
@@ -559,7 +575,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
559
575
|
// +->(hasSubtype) HasEventSource/EventSourceOf
|
|
560
576
|
let node: UAReferenceType | null;
|
|
561
577
|
|
|
562
|
-
if (!(refType instanceof NodeId) && isNodeIdString(refType) || typeof refType === "number") {
|
|
578
|
+
if ((!(refType instanceof NodeId) && isNodeIdString(refType)) || typeof refType === "number") {
|
|
563
579
|
refType = resolveNodeId(refType);
|
|
564
580
|
}
|
|
565
581
|
if (refType instanceof NodeId) {
|
|
@@ -593,13 +609,11 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
593
609
|
public inverseReferenceType(referenceType: string): string {
|
|
594
610
|
assert(typeof referenceType === "string");
|
|
595
611
|
const n1 = this.findReferenceType(referenceType);
|
|
596
|
-
const n2 = this.findReferenceTypeFromInverseName(referenceType);
|
|
597
612
|
if (n1) {
|
|
598
|
-
|
|
599
|
-
return n1.inverseName!.text as string;
|
|
613
|
+
return n1.inverseName?.text as string;
|
|
600
614
|
} else {
|
|
601
|
-
|
|
602
|
-
return n2
|
|
615
|
+
const n2 = this.findReferenceTypeFromInverseName(referenceType);
|
|
616
|
+
return n2?.browseName.toString() || "";
|
|
603
617
|
}
|
|
604
618
|
}
|
|
605
619
|
|
|
@@ -679,53 +693,49 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
679
693
|
/*=
|
|
680
694
|
* construct a simple javascript object with all the default properties of the event
|
|
681
695
|
*
|
|
682
|
-
* @return result.$eventDataSource {BaseNode} the event type node
|
|
683
|
-
* @return result.eventId {NodeId} the
|
|
684
|
-
* ...
|
|
685
|
-
*
|
|
686
696
|
*
|
|
687
697
|
* eventTypeId can be a UAEventType
|
|
688
698
|
*
|
|
689
699
|
* @private
|
|
690
700
|
*/
|
|
691
|
-
public constructEventData(eventTypeId: UAEventType,
|
|
692
|
-
data =
|
|
701
|
+
public constructEventData(eventTypeId: UAEventType, dataInput: Record<string, unknown>): IEventData {
|
|
702
|
+
const data: RaiseEventData = (dataInput || {}) as RaiseEventData;
|
|
693
703
|
|
|
694
704
|
// construct the reference dataStructure to store event Data
|
|
695
|
-
let eventTypeNode = eventTypeId;
|
|
705
|
+
let eventTypeNode: UAEventType | null = eventTypeId;
|
|
696
706
|
|
|
697
707
|
// make sure that eventType is really a object that derived from EventType
|
|
698
708
|
if (eventTypeId instanceof UAObjectTypeImpl) {
|
|
699
|
-
eventTypeNode = this.findEventType(eventTypeId)
|
|
709
|
+
eventTypeNode = this.findEventType(eventTypeId) as UAEventType | null;
|
|
700
710
|
}
|
|
701
|
-
|
|
702
711
|
/* c8 ignore next */
|
|
703
|
-
if (!eventTypeNode) {
|
|
704
|
-
|
|
705
|
-
|
|
712
|
+
if (!eventTypeNode) throw new Error(` cannot find EventType for ${eventTypeId}`);
|
|
713
|
+
|
|
714
|
+
|
|
706
715
|
assert(eventTypeNode instanceof UAObjectTypeImpl, "eventTypeId must represent a UAObjectType");
|
|
707
716
|
|
|
708
717
|
// eventId
|
|
709
|
-
assert(
|
|
710
|
-
!Object.prototype.hasOwnProperty.call(data, "eventId"),
|
|
711
|
-
"eventId constructEventData : options object should not have eventId property"
|
|
712
|
-
);
|
|
718
|
+
assert(!Object.hasOwn(data, "eventId"), "eventId constructEventData : options object should not have eventId property");
|
|
713
719
|
data.eventId = data.eventId || this.generateEventId();
|
|
714
720
|
|
|
715
721
|
// eventType
|
|
716
722
|
data.eventType = { dataType: DataType.NodeId, value: eventTypeNode.nodeId };
|
|
717
723
|
|
|
718
724
|
// sourceNode
|
|
719
|
-
assert(Object.
|
|
725
|
+
assert(Object.hasOwn(data, "sourceNode"), "expecting a source node to be defined");
|
|
720
726
|
data.sourceNode = new Variant(data.sourceNode);
|
|
721
727
|
assert(data.sourceNode.dataType === DataType.NodeId);
|
|
722
728
|
|
|
723
729
|
// sourceName
|
|
724
|
-
const sourceNode = this.findNode(data.sourceNode.value)
|
|
725
|
-
|
|
730
|
+
const sourceNode = this.findNode(data.sourceNode.value);
|
|
731
|
+
if (!sourceNode) {
|
|
732
|
+
warningLog(
|
|
733
|
+
`constructEventData: cannot find sourceNode ${data.sourceNode.value?.toString()} for event ${eventTypeNode.browseName.toString()}`
|
|
734
|
+
);
|
|
735
|
+
}
|
|
726
736
|
data.sourceName = data.sourceName || {
|
|
727
737
|
dataType: DataType.String,
|
|
728
|
-
value: sourceNode
|
|
738
|
+
value: sourceNode?.getDisplayName("en") || ""
|
|
729
739
|
};
|
|
730
740
|
|
|
731
741
|
const nowUTC = new Date();
|
|
@@ -757,14 +767,14 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
757
767
|
throw new Error("BaseObjectType must be defined in the address space");
|
|
758
768
|
}
|
|
759
769
|
|
|
760
|
-
const hasProperty = (data: any, propertyName: string): boolean => Object.
|
|
770
|
+
const hasProperty = (data: any, propertyName: string): boolean => Object.hasOwn(data, propertyName);
|
|
761
771
|
|
|
762
772
|
const visitedProperties: { [key: string]: number } = {};
|
|
763
|
-
const alreadyVisited = (key: string) => Object.
|
|
773
|
+
const alreadyVisited = (key: string) => Object.hasOwn(visitedProperties, key);
|
|
764
774
|
const markAsVisited = (key: string) => (visitedProperties[key] = 1);
|
|
765
775
|
|
|
766
776
|
function _process_var(self: BaseNode, prefixLower: string, prefixStandard: string, node: BaseNode) {
|
|
767
|
-
const lowerName = prefixLower + lowerFirstLetter(node.browseName
|
|
777
|
+
const lowerName = prefixLower + lowerFirstLetter(node.browseName?.name || "");
|
|
768
778
|
const fullBrowsePath = prefixStandard + node.browseName.toString();
|
|
769
779
|
if (alreadyVisited(lowerName)) {
|
|
770
780
|
return;
|
|
@@ -803,7 +813,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
803
813
|
|
|
804
814
|
// verify that all elements of data are valid
|
|
805
815
|
function verify_data_is_valid(data1: Record<string, unknown>) {
|
|
806
|
-
Object.keys(data1).
|
|
816
|
+
Object.keys(data1).forEach((k: string) => {
|
|
807
817
|
if (k === "$eventDataSource") {
|
|
808
818
|
return;
|
|
809
819
|
}
|
|
@@ -815,21 +825,21 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
815
825
|
"' in [ " +
|
|
816
826
|
Object.keys(visitedProperties).join(", ") +
|
|
817
827
|
"] when filling " +
|
|
818
|
-
eventTypeNode
|
|
828
|
+
eventTypeNode?.browseName.toString()
|
|
819
829
|
);
|
|
820
830
|
}
|
|
821
831
|
});
|
|
822
832
|
}
|
|
823
833
|
|
|
824
834
|
const populate_data = (self: any, eventData1: any) => {
|
|
825
|
-
if (sameNodeId(baseObjectType
|
|
835
|
+
if (sameNodeId(baseObjectType?.nodeId, self.nodeId)) {
|
|
826
836
|
return; // nothing to do
|
|
827
837
|
}
|
|
828
838
|
|
|
829
839
|
const baseTypeNodeId = self.subtypeOf;
|
|
830
840
|
/* c8 ignore next */
|
|
831
841
|
if (!baseTypeNodeId) {
|
|
832
|
-
throw new Error(
|
|
842
|
+
throw new Error(`Object ${self.browseName.toString()} with nodeId ${self.nodeId} has no Type`);
|
|
833
843
|
}
|
|
834
844
|
|
|
835
845
|
const baseType = this.findNode(baseTypeNodeId);
|
|
@@ -847,7 +857,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
847
857
|
|
|
848
858
|
// c8 ignore next
|
|
849
859
|
if (doDebug) {
|
|
850
|
-
debugLog(
|
|
860
|
+
debugLog(` ${chalk.bgWhite.cyan(self.browseName.toString())}`);
|
|
851
861
|
}
|
|
852
862
|
|
|
853
863
|
for (const node of children) {
|
|
@@ -867,10 +877,10 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
867
877
|
|
|
868
878
|
const children2 = node.getAggregates();
|
|
869
879
|
if (children2.length > 0) {
|
|
870
|
-
const lowerName = lowerFirstLetter(node.browseName.name
|
|
880
|
+
const lowerName = lowerFirstLetter(node.browseName.name || "");
|
|
871
881
|
const standardName = node.browseName.toString();
|
|
872
882
|
for (const child2 of children2) {
|
|
873
|
-
_process_var(self, lowerName
|
|
883
|
+
_process_var(self, `${lowerName}.`, `${standardName}.`, child2);
|
|
874
884
|
}
|
|
875
885
|
}
|
|
876
886
|
}
|
|
@@ -943,7 +953,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
943
953
|
const empty_targetName_not_in_lastPos = browsePath.relativePath.elements.reduce((prev, e, index) => {
|
|
944
954
|
const is_last = index + 1 === elements_length;
|
|
945
955
|
const isBad = !is_last && (!e.targetName || e.targetName.isEmpty());
|
|
946
|
-
return prev + (
|
|
956
|
+
return prev + (isBad ? 1 : 0);
|
|
947
957
|
}, 0);
|
|
948
958
|
if (empty_targetName_not_in_lastPos) {
|
|
949
959
|
return new BrowsePathResult({ statusCode: StatusCodes.BadBrowseNameInvalid });
|
|
@@ -961,12 +971,8 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
961
971
|
|
|
962
972
|
const explore_element = (curNodeObject: BaseNode, elements: RelativePathElement[], index: number) => {
|
|
963
973
|
const element = elements[index];
|
|
964
|
-
assert(element instanceof RelativePathElement);
|
|
965
|
-
|
|
966
974
|
const is_last = index + 1 === elements.length;
|
|
967
|
-
|
|
968
975
|
const nodeIds = curNodeObject.browseNodeByTargetName(element, is_last);
|
|
969
|
-
|
|
970
976
|
const targets = nodeIds.map((nodeId: NodeId) => {
|
|
971
977
|
return {
|
|
972
978
|
remainingPathIndex: elements.length - index,
|
|
@@ -1013,14 +1019,14 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1013
1019
|
const tmp = this.findNode(dataType);
|
|
1014
1020
|
/* c8 ignore next */
|
|
1015
1021
|
if (!tmp) {
|
|
1016
|
-
throw new Error(
|
|
1022
|
+
throw new Error(`getExtensionObjectConstructor: cannot resolve dataType ${dataType}`);
|
|
1017
1023
|
}
|
|
1018
1024
|
dataType = tmp as UADataType;
|
|
1019
1025
|
}
|
|
1020
1026
|
/* c8 ignore next */
|
|
1021
1027
|
if (!(dataType instanceof UADataTypeImpl)) {
|
|
1022
1028
|
// may be dataType was the NodeId of the "Binary Encoding" node
|
|
1023
|
-
throw new Error(
|
|
1029
|
+
throw new Error(`getExtensionObjectConstructor: dataType has unexpected type${dataType}`);
|
|
1024
1030
|
}
|
|
1025
1031
|
const _dataType = dataType as UADataTypeImpl;
|
|
1026
1032
|
|
|
@@ -1178,7 +1184,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1178
1184
|
folder = this._coerceNode(folder) as UAObject;
|
|
1179
1185
|
/* c8 ignore next */
|
|
1180
1186
|
if (folder && !_isFolder(this, folder)) {
|
|
1181
|
-
throw new Error(
|
|
1187
|
+
throw new Error(`Parent folder must be of FolderType ${folder.typeDefinition.toString()}`);
|
|
1182
1188
|
}
|
|
1183
1189
|
return folder as any as BaseNode;
|
|
1184
1190
|
}
|
|
@@ -1189,7 +1195,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1189
1195
|
* @param modelChange
|
|
1190
1196
|
* @private
|
|
1191
1197
|
*/
|
|
1192
|
-
public _collectModelChange(
|
|
1198
|
+
public _collectModelChange(_view: UAView | null, modelChange: ModelChangeStructureDataType): void {
|
|
1193
1199
|
this._modelChanges.push(modelChange);
|
|
1194
1200
|
}
|
|
1195
1201
|
|
|
@@ -1234,7 +1240,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1234
1240
|
results.push(parent as UAView);
|
|
1235
1241
|
} else {
|
|
1236
1242
|
const key = parent.nodeId.toString();
|
|
1237
|
-
if (Object.
|
|
1243
|
+
if (Object.hasOwn(visitedMap, key)) {
|
|
1238
1244
|
continue;
|
|
1239
1245
|
}
|
|
1240
1246
|
visitedMap[key] = parent;
|
|
@@ -1349,7 +1355,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1349
1355
|
|
|
1350
1356
|
// ----------- now resolve target NodeId;
|
|
1351
1357
|
if (params.nodeId instanceof BaseNodeImpl) {
|
|
1352
|
-
assert(!Object.
|
|
1358
|
+
assert(!Object.hasOwn(params, "node"));
|
|
1353
1359
|
params.node = params.nodeId as BaseNode;
|
|
1354
1360
|
params.nodeId = params.node.nodeId;
|
|
1355
1361
|
} else {
|
|
@@ -1392,14 +1398,6 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1392
1398
|
|
|
1393
1399
|
// -- internal stuff -----------------------------------------------------------------------------------------------
|
|
1394
1400
|
public _coerceNode(node: string | BaseNode | NodeId): BaseNode | null {
|
|
1395
|
-
function hasTypeDefinition(node1: BaseNode) {
|
|
1396
|
-
return (
|
|
1397
|
-
node1.nodeClass === NodeClass.Variable ||
|
|
1398
|
-
node1.nodeClass === NodeClass.Object ||
|
|
1399
|
-
node1.nodeClass === NodeClass.Method
|
|
1400
|
-
);
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
1401
|
// coerce to BaseNode object
|
|
1404
1402
|
if (node instanceof BaseNodeImpl) {
|
|
1405
1403
|
return node as BaseNode;
|
|
@@ -1424,7 +1422,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1424
1422
|
return dataType;
|
|
1425
1423
|
}
|
|
1426
1424
|
if (dataType === 0) {
|
|
1427
|
-
return NodeId.nullNodeId
|
|
1425
|
+
return NodeId.nullNodeId;
|
|
1428
1426
|
}
|
|
1429
1427
|
return this._coerce_Type(dataType, DataTypeIds, "DataTypeIds", AddressSpace.prototype.findDataType);
|
|
1430
1428
|
}
|
|
@@ -1445,7 +1443,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1445
1443
|
|
|
1446
1444
|
/* c8 ignore next */
|
|
1447
1445
|
if (!topMostBaseTypeNode) {
|
|
1448
|
-
throw new Error(
|
|
1446
|
+
throw new Error(`Cannot find topMostBaseTypeNode ${topMostBaseType.toString()}`);
|
|
1449
1447
|
}
|
|
1450
1448
|
assert(topMostBaseTypeNode instanceof BaseNodeImpl);
|
|
1451
1449
|
assert(topMostBaseTypeNode.nodeClass === nodeClass);
|
|
@@ -1463,11 +1461,11 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1463
1461
|
|
|
1464
1462
|
/* c8 ignore next*/
|
|
1465
1463
|
if (!baseTypeNode) {
|
|
1466
|
-
throw new Error(
|
|
1464
|
+
throw new Error(`Cannot find ObjectType or VariableType for ${baseType.toString()}`);
|
|
1467
1465
|
}
|
|
1468
1466
|
/* c8 ignore next */
|
|
1469
1467
|
if (!(baseTypeNode as any).isSubtypeOf) {
|
|
1470
|
-
throw new Error(
|
|
1468
|
+
throw new Error(`Cannot find ObjectType or VariableType for ${baseType.toString()}`);
|
|
1471
1469
|
}
|
|
1472
1470
|
/* c8 ignore next */
|
|
1473
1471
|
if (!(baseTypeNode as any).isSubtypeOf(topMostBaseTypeNode)) {
|
|
@@ -1494,7 +1492,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1494
1492
|
// DataType must be one of Enumeration
|
|
1495
1493
|
const dataTypeNode = this.findDataType(dataType) as UADataType;
|
|
1496
1494
|
if (!dataTypeNode) {
|
|
1497
|
-
throw new Error(
|
|
1495
|
+
throw new Error(` Cannot find DataType ${dataType.toString()} in standard address Space`);
|
|
1498
1496
|
}
|
|
1499
1497
|
|
|
1500
1498
|
const enumerationNode = this.findDataType("Enumeration")!;
|
|
@@ -1504,7 +1502,12 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1504
1502
|
return dataTypeNode.isSubtypeOf(enumerationNode);
|
|
1505
1503
|
}
|
|
1506
1504
|
|
|
1507
|
-
private _coerce_Type(
|
|
1505
|
+
private _coerce_Type(
|
|
1506
|
+
dataType: BaseNode | string | NodeId | number,
|
|
1507
|
+
typeMap: any,
|
|
1508
|
+
typeMapName: string,
|
|
1509
|
+
finderMethod: any
|
|
1510
|
+
): NodeId {
|
|
1508
1511
|
if (typeof dataType === "number") {
|
|
1509
1512
|
return this._coerce_Type(coerceNodeId(dataType), typeMap, typeMapName, finderMethod);
|
|
1510
1513
|
}
|
|
@@ -1554,10 +1557,10 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1554
1557
|
|
|
1555
1558
|
if (!el) {
|
|
1556
1559
|
// verify that node Id exists in standard type map typeMap
|
|
1557
|
-
const find = Object.values(typeMap).filter((a) => a === nodeId
|
|
1560
|
+
const find = Object.values(typeMap).filter((a) => a === nodeId?.value);
|
|
1558
1561
|
/* c8 ignore next */
|
|
1559
1562
|
if (find.length !== 1) {
|
|
1560
|
-
throw new Error(
|
|
1563
|
+
throw new Error(` cannot find ${dataType.toString()} in typeMap ${typeMapName} L = ${find.length}`);
|
|
1561
1564
|
}
|
|
1562
1565
|
}
|
|
1563
1566
|
return nodeId;
|
|
@@ -1577,7 +1580,7 @@ function _getNamespace(addressSpace: AddressSpace, nodeOrNodId: BaseNode | NodeI
|
|
|
1577
1580
|
return addressSpace.getNamespace(nodeId.namespace);
|
|
1578
1581
|
}
|
|
1579
1582
|
|
|
1580
|
-
function _find_by_node_id<T extends BaseNode>(addressSpace: AddressSpace, nodeId: NodeId,
|
|
1583
|
+
function _find_by_node_id<T extends BaseNode>(addressSpace: AddressSpace, nodeId: NodeId, _namespaceIndex?: number): T {
|
|
1581
1584
|
const obj = addressSpace.findNode(nodeId);
|
|
1582
1585
|
return obj as T;
|
|
1583
1586
|
}
|
|
@@ -1590,16 +1593,16 @@ function _find_by_node_id<T extends BaseNode>(addressSpace: AddressSpace, nodeId
|
|
|
1590
1593
|
* @private
|
|
1591
1594
|
*/
|
|
1592
1595
|
function _isFolder(addressSpace: AddressSpace, folder: UAObject): boolean {
|
|
1593
|
-
const folderType = addressSpace.findObjectType("FolderType")
|
|
1596
|
+
const folderType = addressSpace.findObjectType("FolderType") as UAObjectType;
|
|
1594
1597
|
assert(folder instanceof BaseNodeImpl);
|
|
1595
1598
|
assert(folder.typeDefinitionObj);
|
|
1596
1599
|
return folder.typeDefinitionObj.isSubtypeOf(folderType);
|
|
1597
1600
|
}
|
|
1598
1601
|
|
|
1599
1602
|
function _increase_version_number(node: BaseNode | null) {
|
|
1600
|
-
|
|
1603
|
+
const uaNodeVersion = node?.getNodeVersion();
|
|
1601
1604
|
if (uaNodeVersion) {
|
|
1602
|
-
|
|
1605
|
+
const rawValue = uaNodeVersion.readValue().value.value || "";
|
|
1603
1606
|
let previousValue = parseInt(rawValue || "0", 10);
|
|
1604
1607
|
if (Number.isNaN(previousValue)) {
|
|
1605
1608
|
warningLog("NodeVersion was ", rawValue);
|
|
@@ -90,7 +90,7 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
|
|
|
90
90
|
}
|
|
91
91
|
const c = this.condition as UAConditionImpl;
|
|
92
92
|
const isDisabled = !c.getEnabledState();
|
|
93
|
-
const eventData = new EventData(this.condition
|
|
93
|
+
const eventData = new EventData(this.condition);
|
|
94
94
|
|
|
95
95
|
for (const fullBrowsePath of this._map.keys()) {
|
|
96
96
|
const node = this._node_index.get(fullBrowsePath);
|
|
@@ -98,10 +98,10 @@ export class ConditionSnapshotImpl extends EventEmitter implements ConditionSnap
|
|
|
98
98
|
debugLog("cannot node for find key", fullBrowsePath);
|
|
99
99
|
continue;
|
|
100
100
|
}
|
|
101
|
-
if (isDisabled && !Object.
|
|
101
|
+
if (isDisabled && !Object.hasOwn(_varTable, fullBrowsePath)) {
|
|
102
102
|
eventData._createValue(fullBrowsePath, node, disabledVar);
|
|
103
103
|
} else {
|
|
104
|
-
eventData._createValue(fullBrowsePath, node, this._map.get(fullBrowsePath)
|
|
104
|
+
eventData._createValue(fullBrowsePath, node, this._map.get(fullBrowsePath) as Variant);
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
return eventData;
|
|
@@ -185,7 +185,7 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
|
|
|
185
185
|
const statusCode = inner_func(eventId, comment, branch, conditionNode);
|
|
186
186
|
|
|
187
187
|
// record also who did the call
|
|
188
|
-
branch.setClientUserId(context.
|
|
188
|
+
branch.setClientUserId(context.getUserName());
|
|
189
189
|
|
|
190
190
|
callback(null, {
|
|
191
191
|
statusCode
|
package/src/base_node_impl.ts
CHANGED
|
@@ -1031,6 +1031,19 @@ export class BaseNodeImpl extends EventEmitter implements BaseNode {
|
|
|
1031
1031
|
return options.toString();
|
|
1032
1032
|
}
|
|
1033
1033
|
|
|
1034
|
+
public toJSON(): Record<string, unknown> {
|
|
1035
|
+
return {
|
|
1036
|
+
nodeId: this.nodeId.toString(),
|
|
1037
|
+
nodeClass: NodeClass[this.nodeClass],
|
|
1038
|
+
browseName: this.browseName.toString(),
|
|
1039
|
+
displayName: this.displayName.length ? this.displayName[0].text : ""
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
public [Symbol.for("nodejs.util.inspect.custom")](): string {
|
|
1044
|
+
return this.toString();
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1034
1047
|
/**
|
|
1035
1048
|
* @property isFalseSubStateOf
|
|
1036
1049
|
* @type {BaseNode|null}
|