node-opcua-address-space 2.167.0 → 2.169.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.
- 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/src/address_space.d.ts +14 -11
- package/dist/src/address_space.js +55 -54
- package/dist/src/address_space.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.d.ts +8 -8
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js +19 -19
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.d.ts +11 -13
- package/dist/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.js +21 -13
- package/dist/src/alarms_and_conditions/ua_certificate_expiration_alarm_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 +26 -15
- package/dist/src/base_node_impl.js.map +1 -1
- package/dist/src/namespace_impl.d.ts +40 -31
- package/dist/src/namespace_impl.js +174 -161
- package/dist/src/namespace_impl.js.map +1 -1
- package/dist/src/namespace_private.d.ts +12 -4
- package/dist/src/namespace_private.js +1 -4
- package/dist/src/namespace_private.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/tsconfig_base.tsbuildinfo +1 -1
- package/package.json +35 -37
- package/source/loader/namespace_post_step.ts +28 -19
- package/source/session_context.ts +30 -1
- package/src/address_space.ts +113 -109
- package/src/alarms_and_conditions/ua_alarm_condition_impl.ts +26 -28
- package/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.ts +33 -27
- package/src/alarms_and_conditions/ua_condition_impl.ts +1 -1
- package/src/base_node_impl.ts +27 -14
- package/src/namespace_impl.ts +232 -201
- package/src/namespace_private.ts +15 -9
- package/src/ua_method_impl.ts +43 -50
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
|
|
|
@@ -701,22 +715,19 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
701
715
|
|
|
702
716
|
/* c8 ignore next */
|
|
703
717
|
if (!eventTypeNode) {
|
|
704
|
-
throw new Error(
|
|
718
|
+
throw new Error(` cannot find EvenType for ${eventTypeId}`);
|
|
705
719
|
}
|
|
706
720
|
assert(eventTypeNode instanceof UAObjectTypeImpl, "eventTypeId must represent a UAObjectType");
|
|
707
721
|
|
|
708
722
|
// eventId
|
|
709
|
-
assert(
|
|
710
|
-
!Object.prototype.hasOwnProperty.call(data, "eventId"),
|
|
711
|
-
"eventId constructEventData : options object should not have eventId property"
|
|
712
|
-
);
|
|
723
|
+
assert(!Object.hasOwn(data, "eventId"), "eventId constructEventData : options object should not have eventId property");
|
|
713
724
|
data.eventId = data.eventId || this.generateEventId();
|
|
714
725
|
|
|
715
726
|
// eventType
|
|
716
727
|
data.eventType = { dataType: DataType.NodeId, value: eventTypeNode.nodeId };
|
|
717
728
|
|
|
718
729
|
// sourceNode
|
|
719
|
-
assert(Object.
|
|
730
|
+
assert(Object.hasOwn(data, "sourceNode"), "expecting a source node to be defined");
|
|
720
731
|
data.sourceNode = new Variant(data.sourceNode);
|
|
721
732
|
assert(data.sourceNode.dataType === DataType.NodeId);
|
|
722
733
|
|
|
@@ -757,14 +768,14 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
757
768
|
throw new Error("BaseObjectType must be defined in the address space");
|
|
758
769
|
}
|
|
759
770
|
|
|
760
|
-
const hasProperty = (data: any, propertyName: string): boolean => Object.
|
|
771
|
+
const hasProperty = (data: any, propertyName: string): boolean => Object.hasOwn(data, propertyName);
|
|
761
772
|
|
|
762
773
|
const visitedProperties: { [key: string]: number } = {};
|
|
763
|
-
const alreadyVisited = (key: string) => Object.
|
|
774
|
+
const alreadyVisited = (key: string) => Object.hasOwn(visitedProperties, key);
|
|
764
775
|
const markAsVisited = (key: string) => (visitedProperties[key] = 1);
|
|
765
776
|
|
|
766
777
|
function _process_var(self: BaseNode, prefixLower: string, prefixStandard: string, node: BaseNode) {
|
|
767
|
-
const lowerName = prefixLower + lowerFirstLetter(node.browseName
|
|
778
|
+
const lowerName = prefixLower + lowerFirstLetter(node.browseName?.name || "");
|
|
768
779
|
const fullBrowsePath = prefixStandard + node.browseName.toString();
|
|
769
780
|
if (alreadyVisited(lowerName)) {
|
|
770
781
|
return;
|
|
@@ -803,7 +814,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
803
814
|
|
|
804
815
|
// verify that all elements of data are valid
|
|
805
816
|
function verify_data_is_valid(data1: Record<string, unknown>) {
|
|
806
|
-
Object.keys(data1).
|
|
817
|
+
Object.keys(data1).forEach((k: string) => {
|
|
807
818
|
if (k === "$eventDataSource") {
|
|
808
819
|
return;
|
|
809
820
|
}
|
|
@@ -822,14 +833,14 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
822
833
|
}
|
|
823
834
|
|
|
824
835
|
const populate_data = (self: any, eventData1: any) => {
|
|
825
|
-
if (sameNodeId(baseObjectType
|
|
836
|
+
if (sameNodeId(baseObjectType?.nodeId, self.nodeId)) {
|
|
826
837
|
return; // nothing to do
|
|
827
838
|
}
|
|
828
839
|
|
|
829
840
|
const baseTypeNodeId = self.subtypeOf;
|
|
830
841
|
/* c8 ignore next */
|
|
831
842
|
if (!baseTypeNodeId) {
|
|
832
|
-
throw new Error(
|
|
843
|
+
throw new Error(`Object ${self.browseName.toString()} with nodeId ${self.nodeId} has no Type`);
|
|
833
844
|
}
|
|
834
845
|
|
|
835
846
|
const baseType = this.findNode(baseTypeNodeId);
|
|
@@ -847,7 +858,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
847
858
|
|
|
848
859
|
// c8 ignore next
|
|
849
860
|
if (doDebug) {
|
|
850
|
-
debugLog(
|
|
861
|
+
debugLog(` ${chalk.bgWhite.cyan(self.browseName.toString())}`);
|
|
851
862
|
}
|
|
852
863
|
|
|
853
864
|
for (const node of children) {
|
|
@@ -867,10 +878,10 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
867
878
|
|
|
868
879
|
const children2 = node.getAggregates();
|
|
869
880
|
if (children2.length > 0) {
|
|
870
|
-
const lowerName = lowerFirstLetter(node.browseName.name
|
|
881
|
+
const lowerName = lowerFirstLetter(node.browseName.name || "");
|
|
871
882
|
const standardName = node.browseName.toString();
|
|
872
883
|
for (const child2 of children2) {
|
|
873
|
-
_process_var(self, lowerName
|
|
884
|
+
_process_var(self, `${lowerName}.`, `${standardName}.`, child2);
|
|
874
885
|
}
|
|
875
886
|
}
|
|
876
887
|
}
|
|
@@ -943,7 +954,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
943
954
|
const empty_targetName_not_in_lastPos = browsePath.relativePath.elements.reduce((prev, e, index) => {
|
|
944
955
|
const is_last = index + 1 === elements_length;
|
|
945
956
|
const isBad = !is_last && (!e.targetName || e.targetName.isEmpty());
|
|
946
|
-
return prev + (
|
|
957
|
+
return prev + (isBad ? 1 : 0);
|
|
947
958
|
}, 0);
|
|
948
959
|
if (empty_targetName_not_in_lastPos) {
|
|
949
960
|
return new BrowsePathResult({ statusCode: StatusCodes.BadBrowseNameInvalid });
|
|
@@ -961,12 +972,8 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
961
972
|
|
|
962
973
|
const explore_element = (curNodeObject: BaseNode, elements: RelativePathElement[], index: number) => {
|
|
963
974
|
const element = elements[index];
|
|
964
|
-
assert(element instanceof RelativePathElement);
|
|
965
|
-
|
|
966
975
|
const is_last = index + 1 === elements.length;
|
|
967
|
-
|
|
968
976
|
const nodeIds = curNodeObject.browseNodeByTargetName(element, is_last);
|
|
969
|
-
|
|
970
977
|
const targets = nodeIds.map((nodeId: NodeId) => {
|
|
971
978
|
return {
|
|
972
979
|
remainingPathIndex: elements.length - index,
|
|
@@ -1013,14 +1020,14 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1013
1020
|
const tmp = this.findNode(dataType);
|
|
1014
1021
|
/* c8 ignore next */
|
|
1015
1022
|
if (!tmp) {
|
|
1016
|
-
throw new Error(
|
|
1023
|
+
throw new Error(`getExtensionObjectConstructor: cannot resolve dataType ${dataType}`);
|
|
1017
1024
|
}
|
|
1018
1025
|
dataType = tmp as UADataType;
|
|
1019
1026
|
}
|
|
1020
1027
|
/* c8 ignore next */
|
|
1021
1028
|
if (!(dataType instanceof UADataTypeImpl)) {
|
|
1022
1029
|
// may be dataType was the NodeId of the "Binary Encoding" node
|
|
1023
|
-
throw new Error(
|
|
1030
|
+
throw new Error(`getExtensionObjectConstructor: dataType has unexpected type${dataType}`);
|
|
1024
1031
|
}
|
|
1025
1032
|
const _dataType = dataType as UADataTypeImpl;
|
|
1026
1033
|
|
|
@@ -1178,7 +1185,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1178
1185
|
folder = this._coerceNode(folder) as UAObject;
|
|
1179
1186
|
/* c8 ignore next */
|
|
1180
1187
|
if (folder && !_isFolder(this, folder)) {
|
|
1181
|
-
throw new Error(
|
|
1188
|
+
throw new Error(`Parent folder must be of FolderType ${folder.typeDefinition.toString()}`);
|
|
1182
1189
|
}
|
|
1183
1190
|
return folder as any as BaseNode;
|
|
1184
1191
|
}
|
|
@@ -1189,7 +1196,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1189
1196
|
* @param modelChange
|
|
1190
1197
|
* @private
|
|
1191
1198
|
*/
|
|
1192
|
-
public _collectModelChange(
|
|
1199
|
+
public _collectModelChange(_view: UAView | null, modelChange: ModelChangeStructureDataType): void {
|
|
1193
1200
|
this._modelChanges.push(modelChange);
|
|
1194
1201
|
}
|
|
1195
1202
|
|
|
@@ -1234,7 +1241,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1234
1241
|
results.push(parent as UAView);
|
|
1235
1242
|
} else {
|
|
1236
1243
|
const key = parent.nodeId.toString();
|
|
1237
|
-
if (Object.
|
|
1244
|
+
if (Object.hasOwn(visitedMap, key)) {
|
|
1238
1245
|
continue;
|
|
1239
1246
|
}
|
|
1240
1247
|
visitedMap[key] = parent;
|
|
@@ -1349,7 +1356,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1349
1356
|
|
|
1350
1357
|
// ----------- now resolve target NodeId;
|
|
1351
1358
|
if (params.nodeId instanceof BaseNodeImpl) {
|
|
1352
|
-
assert(!Object.
|
|
1359
|
+
assert(!Object.hasOwn(params, "node"));
|
|
1353
1360
|
params.node = params.nodeId as BaseNode;
|
|
1354
1361
|
params.nodeId = params.node.nodeId;
|
|
1355
1362
|
} else {
|
|
@@ -1392,14 +1399,6 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1392
1399
|
|
|
1393
1400
|
// -- internal stuff -----------------------------------------------------------------------------------------------
|
|
1394
1401
|
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
1402
|
// coerce to BaseNode object
|
|
1404
1403
|
if (node instanceof BaseNodeImpl) {
|
|
1405
1404
|
return node as BaseNode;
|
|
@@ -1424,7 +1423,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1424
1423
|
return dataType;
|
|
1425
1424
|
}
|
|
1426
1425
|
if (dataType === 0) {
|
|
1427
|
-
return NodeId.nullNodeId
|
|
1426
|
+
return NodeId.nullNodeId;
|
|
1428
1427
|
}
|
|
1429
1428
|
return this._coerce_Type(dataType, DataTypeIds, "DataTypeIds", AddressSpace.prototype.findDataType);
|
|
1430
1429
|
}
|
|
@@ -1445,7 +1444,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1445
1444
|
|
|
1446
1445
|
/* c8 ignore next */
|
|
1447
1446
|
if (!topMostBaseTypeNode) {
|
|
1448
|
-
throw new Error(
|
|
1447
|
+
throw new Error(`Cannot find topMostBaseTypeNode ${topMostBaseType.toString()}`);
|
|
1449
1448
|
}
|
|
1450
1449
|
assert(topMostBaseTypeNode instanceof BaseNodeImpl);
|
|
1451
1450
|
assert(topMostBaseTypeNode.nodeClass === nodeClass);
|
|
@@ -1463,11 +1462,11 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1463
1462
|
|
|
1464
1463
|
/* c8 ignore next*/
|
|
1465
1464
|
if (!baseTypeNode) {
|
|
1466
|
-
throw new Error(
|
|
1465
|
+
throw new Error(`Cannot find ObjectType or VariableType for ${baseType.toString()}`);
|
|
1467
1466
|
}
|
|
1468
1467
|
/* c8 ignore next */
|
|
1469
1468
|
if (!(baseTypeNode as any).isSubtypeOf) {
|
|
1470
|
-
throw new Error(
|
|
1469
|
+
throw new Error(`Cannot find ObjectType or VariableType for ${baseType.toString()}`);
|
|
1471
1470
|
}
|
|
1472
1471
|
/* c8 ignore next */
|
|
1473
1472
|
if (!(baseTypeNode as any).isSubtypeOf(topMostBaseTypeNode)) {
|
|
@@ -1494,7 +1493,7 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1494
1493
|
// DataType must be one of Enumeration
|
|
1495
1494
|
const dataTypeNode = this.findDataType(dataType) as UADataType;
|
|
1496
1495
|
if (!dataTypeNode) {
|
|
1497
|
-
throw new Error(
|
|
1496
|
+
throw new Error(` Cannot find DataType ${dataType.toString()} in standard address Space`);
|
|
1498
1497
|
}
|
|
1499
1498
|
|
|
1500
1499
|
const enumerationNode = this.findDataType("Enumeration")!;
|
|
@@ -1504,7 +1503,12 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1504
1503
|
return dataTypeNode.isSubtypeOf(enumerationNode);
|
|
1505
1504
|
}
|
|
1506
1505
|
|
|
1507
|
-
private _coerce_Type(
|
|
1506
|
+
private _coerce_Type(
|
|
1507
|
+
dataType: BaseNode | string | NodeId | number,
|
|
1508
|
+
typeMap: any,
|
|
1509
|
+
typeMapName: string,
|
|
1510
|
+
finderMethod: any
|
|
1511
|
+
): NodeId {
|
|
1508
1512
|
if (typeof dataType === "number") {
|
|
1509
1513
|
return this._coerce_Type(coerceNodeId(dataType), typeMap, typeMapName, finderMethod);
|
|
1510
1514
|
}
|
|
@@ -1554,10 +1558,10 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
1554
1558
|
|
|
1555
1559
|
if (!el) {
|
|
1556
1560
|
// verify that node Id exists in standard type map typeMap
|
|
1557
|
-
const find = Object.values(typeMap).filter((a) => a === nodeId
|
|
1561
|
+
const find = Object.values(typeMap).filter((a) => a === nodeId?.value);
|
|
1558
1562
|
/* c8 ignore next */
|
|
1559
1563
|
if (find.length !== 1) {
|
|
1560
|
-
throw new Error(
|
|
1564
|
+
throw new Error(` cannot find ${dataType.toString()} in typeMap ${typeMapName} L = ${find.length}`);
|
|
1561
1565
|
}
|
|
1562
1566
|
}
|
|
1563
1567
|
return nodeId;
|
|
@@ -1577,7 +1581,7 @@ function _getNamespace(addressSpace: AddressSpace, nodeOrNodId: BaseNode | NodeI
|
|
|
1577
1581
|
return addressSpace.getNamespace(nodeId.namespace);
|
|
1578
1582
|
}
|
|
1579
1583
|
|
|
1580
|
-
function _find_by_node_id<T extends BaseNode>(addressSpace: AddressSpace, nodeId: NodeId,
|
|
1584
|
+
function _find_by_node_id<T extends BaseNode>(addressSpace: AddressSpace, nodeId: NodeId, _namespaceIndex?: number): T {
|
|
1581
1585
|
const obj = addressSpace.findNode(nodeId);
|
|
1582
1586
|
return obj as T;
|
|
1583
1587
|
}
|
|
@@ -1590,16 +1594,16 @@ function _find_by_node_id<T extends BaseNode>(addressSpace: AddressSpace, nodeId
|
|
|
1590
1594
|
* @private
|
|
1591
1595
|
*/
|
|
1592
1596
|
function _isFolder(addressSpace: AddressSpace, folder: UAObject): boolean {
|
|
1593
|
-
const folderType = addressSpace.findObjectType("FolderType")
|
|
1597
|
+
const folderType = addressSpace.findObjectType("FolderType") as UAObjectType;
|
|
1594
1598
|
assert(folder instanceof BaseNodeImpl);
|
|
1595
1599
|
assert(folder.typeDefinitionObj);
|
|
1596
1600
|
return folder.typeDefinitionObj.isSubtypeOf(folderType);
|
|
1597
1601
|
}
|
|
1598
1602
|
|
|
1599
1603
|
function _increase_version_number(node: BaseNode | null) {
|
|
1600
|
-
|
|
1604
|
+
const uaNodeVersion = node?.getNodeVersion();
|
|
1601
1605
|
if (uaNodeVersion) {
|
|
1602
|
-
|
|
1606
|
+
const rawValue = uaNodeVersion.readValue().value.value || "";
|
|
1603
1607
|
let previousValue = parseInt(rawValue || "0", 10);
|
|
1604
1608
|
if (Number.isNaN(previousValue)) {
|
|
1605
1609
|
warningLog("NodeVersion was ", rawValue);
|