node-opcua-address-space 2.82.0 → 2.84.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.
@@ -49,17 +49,35 @@ const g_weakMap = new WeakMap();
49
49
 
50
50
  const warningLog = make_warningLog(__filename);
51
51
 
52
+ interface BaseNodeCacheInner {
53
+ typeDefinition?: NodeId;
54
+ _childByNameMap?: Record<string, BaseNode>;
55
+ typeDefinitionObj?: UAVariableType | UAObjectType | null;
56
+ _aggregates?: BaseNode[];
57
+ _components?: BaseNode[];
58
+ _properties?: BaseNode[];
59
+ _notifiers?: BaseNode[];
60
+ _eventSources?: BaseNode[];
61
+ _methods?: UAMethod[];
62
+ _ref?: Record<string, UAReference[]>;
63
+ _encoding?: Record<string, UAObject | null>;
64
+ _subtype_id?: Record<string, UAReferenceType[]> | null;
65
+ _subtype_idx?: Record<string, UAReferenceType> | null;
66
+ _subtype_idxVersion?: number;
67
+ _allSubTypes?: UAReferenceType[] | null;
68
+ _allSubTypesVersion?: number;
69
+ _subtypeOfObj?: BaseNode | null;
70
+ }
71
+
52
72
  interface BaseNodeCache {
53
73
  __address_space: IAddressSpace | null;
54
74
  _browseFilter?: (this: BaseNode, context?: ISessionContext) => boolean;
55
- _cache: any;
75
+ _cache: BaseNodeCacheInner;
56
76
  _description?: LocalizedText;
57
77
  _displayName: LocalizedText[];
58
78
  _parent?: BaseNode | null;
59
-
60
79
  _back_referenceIdx: { [key: string]: UAReference };
61
80
  _referenceIdx: { [key: string]: UAReference };
62
-
63
81
  _subtype_idxVersion: number;
64
82
  _subtype_idx: any;
65
83
  }
@@ -100,7 +118,7 @@ export function BaseNode_getPrivate(self: BaseNode): BaseNodeCache {
100
118
  return g_weakMap.get(self);
101
119
  }
102
120
 
103
- export function BaseNode_getCache(node: BaseNode): any {
121
+ export function BaseNode_getCache(node: BaseNode): BaseNodeCacheInner {
104
122
  return BaseNode_getPrivate(node)._cache;
105
123
  }
106
124
  export function BaseNode_clearCache(node: BaseNode): void {
@@ -484,7 +502,8 @@ function _clone_collection_new(
484
502
  }
485
503
 
486
504
  if (optionalFilter && node && !optionalFilter.shouldKeep(node)) {
487
- doTrace && traceLog(extraInfo.pad(), "skipping optional ", node.browseName.toString(), "that doesn't appear in the filter");
505
+ doTrace &&
506
+ traceLog(extraInfo.pad(), "skipping optional ", node.browseName.toString(), "that doesn't appear in the filter");
488
507
  continue; // skip this node
489
508
  }
490
509
  const key = node.browseName.toString();
@@ -541,7 +560,7 @@ function _extractInterfaces2(typeDefinitionNode: UAObjectType | UAVariableType,
541
560
 
542
561
  const hasInterfaceReference = addressSpace.findReferenceType("HasInterface");
543
562
  if (!hasInterfaceReference) {
544
- // this version of the standard UA namespace doesn't support Interface yet
563
+ // this version of the standard UA namespace doesn't support Interface yet
545
564
  return [];
546
565
  }
547
566
  // example:
@@ -669,10 +688,7 @@ function _cloneInterface(
669
688
  const interfaces = _extractInterfaces2(typeDefinitionNode, extraInfo);
670
689
  if (interfaces.length === 0) {
671
690
  if (doTrace) {
672
- traceLog(
673
- extraInfo.pad(),
674
- chalk.yellow("No interface for ", node.browseName.toString(), node.nodeId.toString())
675
- );
691
+ traceLog(extraInfo.pad(), chalk.yellow("No interface for ", node.browseName.toString(), node.nodeId.toString()));
676
692
  }
677
693
  return;
678
694
  }
@@ -797,25 +813,25 @@ export function _clone<T extends UAObject | UAVariable | UAMethod>(
797
813
  const browseNameMap = new Set<string>();
798
814
  _clone_children_references(this, cloneObj, options.copyAlsoModellingRules, newFilter!, extraInfo, browseNameMap);
799
815
 
800
- //
801
- let typeDefinitionNode: UAVariableType | UAObjectType | null = this.typeDefinitionObj;
802
- while (typeDefinitionNode) {
803
- doTrace &&
804
- traceLog(
805
- extraInfo?.pad(),
806
- chalk.blueBright("---------------------- Exploring ", typeDefinitionNode.browseName.toString())
816
+ if (this.nodeClass === NodeClass.Object || this.nodeClass === NodeClass.Variable) {
817
+ let typeDefinitionNode: UAVariableType | UAObjectType | null = this.typeDefinitionObj;
818
+ while (typeDefinitionNode) {
819
+ doTrace &&
820
+ traceLog(
821
+ extraInfo?.pad(),
822
+ chalk.blueBright("---------------------- Exploring ", typeDefinitionNode.browseName.toString())
823
+ );
824
+ _clone_children_references(
825
+ typeDefinitionNode,
826
+ cloneObj,
827
+ options.copyAlsoModellingRules,
828
+ newFilter,
829
+ extraInfo,
830
+ browseNameMap
807
831
  );
808
- _clone_children_references(
809
- typeDefinitionNode,
810
- cloneObj,
811
- options.copyAlsoModellingRules,
812
- newFilter,
813
- extraInfo,
814
- browseNameMap
815
- );
816
- typeDefinitionNode = typeDefinitionNode.subtypeOfObj;
832
+ typeDefinitionNode = typeDefinitionNode.subtypeOfObj;
833
+ }
817
834
  }
818
-
819
835
  _clone_non_hierarchical_references(this, cloneObj, options.copyAlsoModellingRules, newFilter, extraInfo, browseNameMap);
820
836
  }
821
837
  cloneObj.propagate_back_references();
@@ -50,7 +50,11 @@ import { SessionContext } from "../index_current";
50
50
 
51
51
  import { DefinitionMap2, TypeInfo } from "../../source/loader/make_xml_extension_object_parser";
52
52
  import { makeDefinitionMap } from "../../source/loader/decode_xml_extension_object";
53
- import { constructNamespaceDependency, constructNamespacePriorityTable, hasHigherPriorityThan } from "./construct_namespace_dependency";
53
+ import {
54
+ constructNamespaceDependency,
55
+ constructNamespacePriorityTable,
56
+ hasHigherPriorityThan
57
+ } from "./construct_namespace_dependency";
54
58
 
55
59
  // tslint:disable:no-var-requires
56
60
  const XMLWriter = require("xml-writer");
@@ -628,37 +632,37 @@ function _dumpValue(xw: XmlWriter, node: UAVariable | UAVariableType, value: Var
628
632
  if (isExtensionObject) {
629
633
  const encodeXml = _dumpVariantExtensionObjectValue2.bind(null, xw, dataTypeNode);
630
634
 
631
- if (value.arrayType === VariantArrayType.Array) {
632
- startElementEx(xw, uax, `ListOf${baseDataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
633
- value.value.forEach(encodeXml);
634
- restoreDefaultNamespace(xw);
635
- xw.endElement();
636
- } else if (value.arrayType === VariantArrayType.Scalar) {
637
- encodeXml(value.value);
638
- } else {
639
- errorLog(node.toString());
640
- errorLog("_dumpValue : unsupported case , Matrix of ExtensionObjects");
641
- // throw new Error("Unsupported case");
635
+ switch (value.arrayType) {
636
+ case VariantArrayType.Matrix:
637
+ case VariantArrayType.Array:
638
+ startElementEx(xw, uax, `ListOf${baseDataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
639
+ value.value.forEach(encodeXml);
640
+ restoreDefaultNamespace(xw);
641
+ xw.endElement();
642
+ break;
643
+ case VariantArrayType.Scalar:
644
+ encodeXml(value.value);
645
+ break;
646
+ default:
647
+ errorLog(node.toString());
648
+ errorLog("_dumpValue : unsupported arrayType: ", value.arrayType);
642
649
  }
643
650
  } else {
644
651
  const encodeXml = _dumpVariantValue.bind(null, xw, value.dataType, node);
645
- if (value.arrayType === VariantArrayType.Matrix) {
646
- // console.log("Warning _dumpValue : Matrix not supported yet");
647
- startElementEx(xw, uax, `ListOf${dataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
648
- value.value.forEach(encodeXml);
649
- restoreDefaultNamespace(xw);
650
- xw.endElement();
651
- } else if (value.arrayType === VariantArrayType.Array) {
652
- startElementEx(xw, uax, `ListOf${dataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
653
- value.value.forEach(encodeXml);
654
- restoreDefaultNamespace(xw);
655
- xw.endElement();
656
- } else if (value.arrayType === VariantArrayType.Scalar) {
657
- encodeXml(value.value);
658
- } else {
659
- errorLog(node.toString());
660
- errorLog("_dumpValue : unsupported case , Matrix");
661
- // xx throw new Error("Unsupported case");
652
+ switch (value.arrayType) {
653
+ case VariantArrayType.Matrix:
654
+ case VariantArrayType.Array:
655
+ startElementEx(xw, uax, `ListOf${dataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
656
+ value.value.forEach(encodeXml);
657
+ restoreDefaultNamespace(xw);
658
+ xw.endElement();
659
+ break;
660
+ case VariantArrayType.Scalar:
661
+ encodeXml(value.value);
662
+ break;
663
+ default:
664
+ errorLog(node.toString());
665
+ errorLog("_dumpValue : unsupported arrayType: ", value.arrayType);
662
666
  }
663
667
  }
664
668
 
@@ -675,7 +679,6 @@ function _dumpArrayDimensionsAttribute(xw: XmlWriter, node: UAVariableType | UAV
675
679
  }
676
680
 
677
681
  function visitUANode(node: BaseNode, data: DumpData, forward: boolean) {
678
-
679
682
  const addressSpace = node.addressSpace;
680
683
 
681
684
  // visit references
@@ -800,7 +803,7 @@ function dumpCommonAttributes(xw: XmlWriter, node: BaseNode) {
800
803
  }
801
804
  }
802
805
  if (Object.prototype.hasOwnProperty.call(node, "minimumSamplingInterval")) {
803
- const minimumSamplingInterval =(node as UAVariable).minimumSamplingInterval;
806
+ const minimumSamplingInterval = (node as UAVariable).minimumSamplingInterval;
804
807
  if (minimumSamplingInterval > 0) {
805
808
  xw.writeAttribute("MinimumSamplingInterval", minimumSamplingInterval);
806
809
  }
@@ -1030,11 +1033,11 @@ function dumpUAVariableType(xw: XmlWriter, node: UAVariableType) {
1030
1033
  // throw new Error(" cannot find datatype " + node.dataType);
1031
1034
  console.log(
1032
1035
  " cannot find datatype " +
1033
- node.dataType +
1034
- " for node " +
1035
- node.browseName.toString() +
1036
- " id =" +
1037
- node.nodeId.toString()
1036
+ node.dataType +
1037
+ " for node " +
1038
+ node.browseName.toString() +
1039
+ " id =" +
1040
+ node.nodeId.toString()
1038
1041
  );
1039
1042
  } else {
1040
1043
  const dataTypeName = b(xw, resolveDataTypeName(addressSpace, dataTypeNode.nodeId));
@@ -1063,6 +1066,7 @@ function dumpUAObject(xw: XmlWriter, node: UAObject) {
1063
1066
  _dumpUAObject(xw, node);
1064
1067
  xw.writeComment("Object - " + b(xw, node.browseName) + " }}}} ");
1065
1068
  }
1069
+
1066
1070
  function _dumpUAObject(xw: XmlWriter, node: UAObject) {
1067
1071
  assert(node.nodeClass === NodeClass.Object);
1068
1072
  xw.visitedNode = xw.visitedNode || {};
@@ -1101,9 +1105,7 @@ function dumpElementInFolder(xw: XmlWriter, node: BaseNodeImpl) {
1101
1105
 
1102
1106
  function dumpAggregates(xw: XmlWriter, node: BaseNode) {
1103
1107
  // Xx xw.writeComment("Aggregates {{ ");
1104
- const aggregates = node
1105
- .getAggregates()
1106
- .sort(sortByBrowseName);
1108
+ const aggregates = node.getAggregates().sort(sortByBrowseName);
1107
1109
  // const aggregates = node.findReferencesExAsObject("Aggregates", BrowseDirection.Forward);
1108
1110
 
1109
1111
  for (const aggregate of aggregates.sort(sortByNodeId)) {
@@ -1242,7 +1244,6 @@ function writeAliases(xw: XmlWriter, aliases: Record<string, NodeIdString>) {
1242
1244
  xw.endElement();
1243
1245
  }
1244
1246
 
1245
-
1246
1247
  export function constructNamespaceTranslationTable(dependency: INamespace[]): ITranslationTable {
1247
1248
  const translationTable: ITranslationTable = {};
1248
1249
  for (let i = 0; i < dependency.length; i++) {
@@ -1329,8 +1330,6 @@ function makeTypeXsd(namespaceUri: string): string {
1329
1330
 
1330
1331
  // eslint-disable-next-line max-statements
1331
1332
  NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1332
-
1333
-
1334
1333
  const namespaceArrayNode = this.addressSpace.findNode(VariableIds.Server_NamespaceArray);
1335
1334
  const namespaceArray: string[] = namespaceArrayNode
1336
1335
  ? namespaceArrayNode.readAttribute(null, AttributeIds.Value).value.value
@@ -1343,7 +1342,6 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1343
1342
  const translationTable = constructNamespaceTranslationTable(dependency);
1344
1343
  xw.translationTable = translationTable;
1345
1344
 
1346
-
1347
1345
  xw.startDocument({ encoding: "utf-8", version: "1.0" });
1348
1346
  xw.startElement("UANodeSet");
1349
1347
 
@@ -31,7 +31,6 @@ import { get_subtypeOf } from "./tool_isSupertypeOf";
31
31
  import { get_subtypeOfObj } from "./tool_isSupertypeOf";
32
32
  import { BaseNode_getCache } from "./base_node_private";
33
33
 
34
-
35
34
  export interface UADataTypeImpl {
36
35
  _extensionObjectConstructor: ExtensionObjectConstructorFuncWithSchema;
37
36
  }
@@ -149,8 +148,9 @@ export class UADataTypeImpl extends BaseNodeImpl implements UADataType {
149
148
 
150
149
  public getEncodingNode(encoding_name: string): UAObject | null {
151
150
  const _cache = BaseNode_getCache(this);
151
+ _cache._encoding = _cache._encoding || {};
152
152
  const key = encoding_name + "Node";
153
- if (_cache[key] === undefined) {
153
+ if (_cache._encoding[key] === undefined) {
154
154
  assert(encoding_name === "Default Binary" || encoding_name === "Default XML" || encoding_name === "Default JSON");
155
155
  // could be binary or xml
156
156
  const refs = this.findReferences("HasEncoding", true);
@@ -160,24 +160,18 @@ export class UADataTypeImpl extends BaseNodeImpl implements UADataType {
160
160
  .filter((obj: any) => obj !== null)
161
161
  .filter((obj: any) => obj.browseName.toString() === encoding_name);
162
162
  const node = encoding.length === 0 ? null : (encoding[0] as UAObject);
163
- _cache[key] = node;
163
+ _cache._encoding[key] = node;
164
164
  }
165
- return _cache[key];
165
+ return _cache._encoding[key];
166
166
  }
167
167
 
168
168
  public getEncodingNodeId(encoding_name: string): ExpandedNodeId | null {
169
- const _cache = BaseNode_getCache(this);
170
- const key = encoding_name + "NodeId";
171
- if (_cache[key] === undefined) {
172
- const encoding = this.getEncodingNode(encoding_name);
173
- if (encoding) {
174
- const namespaceUri = this.addressSpace.getNamespaceUri(encoding.nodeId.namespace);
175
- _cache[key] = ExpandedNodeId.fromNodeId(encoding.nodeId, namespaceUri);
176
- } else {
177
- _cache[key] = null;
178
- }
169
+ const encoding = this.getEncodingNode(encoding_name);
170
+ if (!encoding) {
171
+ return null;
179
172
  }
180
- return _cache[key];
173
+ const namespaceUri = this.addressSpace.getNamespaceUri(encoding.nodeId.namespace);
174
+ return ExpandedNodeId.fromNodeId(encoding.nodeId, namespaceUri);
181
175
  }
182
176
  /**
183
177
  * returns the encoding of this node's
@@ -56,7 +56,7 @@ function _getAllSubtypes(ref: UAReferenceType) {
56
56
  function _internal_getSubtypeIndex(referenceType: UAReferenceType): { [key: string]: UAReferenceTypePublic } {
57
57
  const possibleReferenceTypes = _getAllSubtypes(referenceType);
58
58
  // create a index of reference type with browseName as key for faster search
59
- const keys: any = {};
59
+ const keys: Record<string, UAReferenceType> = {};
60
60
  for (const refType of possibleReferenceTypes) {
61
61
  keys[refType.nodeId.toString()] = refType;
62
62
  }
@@ -65,7 +65,7 @@ function _internal_getSubtypeIndex(referenceType: UAReferenceType): { [key: stri
65
65
 
66
66
  function _getSubtypeIndex(referenceType: UAReferenceType): { [key: string]: UAReferenceTypePublic } {
67
67
  const _cache = BaseNode_getCache(referenceType);
68
- if (!_cache._subtype_idx || _cache._subtype_idxVersion < ReferenceTypeCounter.count) {
68
+ if (!_cache._subtype_idx || (_cache._subtype_idxVersion && _cache._subtype_idxVersion < ReferenceTypeCounter.count)) {
69
69
  // the cache need to be invalidated
70
70
  _cache._subtype_idx = null;
71
71
  }
@@ -1388,7 +1388,7 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
1388
1388
  return false;
1389
1389
  }
1390
1390
  return checkExtensionObjectIsCorrectScalar.call(this, extObj);
1391
- } else if (this.valueRank === 1) {
1391
+ } else if (this.valueRank >= 1) {
1392
1392
  /** array */
1393
1393
  if (!(extObj instanceof Array)) {
1394
1394
  // let's coerce this scalar into an 1-element array if it is a valid extension object