node-opcua-address-space 2.76.2 → 2.78.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.
Files changed (73) hide show
  1. package/dist/source/continuation_points/continuation_point_manager.d.ts +59 -0
  2. package/dist/source/continuation_points/continuation_point_manager.js +6 -6
  3. package/dist/source/continuation_points/continuation_point_manager.js.map +1 -1
  4. package/dist/source/index.d.ts +1 -0
  5. package/dist/source/index.js +1 -0
  6. package/dist/source/index.js.map +1 -1
  7. package/dist/source/loader/ensure_datatype_extracted.js +25 -0
  8. package/dist/source/loader/ensure_datatype_extracted.js.map +1 -1
  9. package/dist/source/loader/generateAddressSpaceRaw.d.ts +2 -1
  10. package/dist/source/loader/generateAddressSpaceRaw.js +2 -2
  11. package/dist/source/loader/generateAddressSpaceRaw.js.map +1 -1
  12. package/dist/source/loader/load_nodeset2.d.ts +7 -3
  13. package/dist/source/loader/load_nodeset2.js +66 -31
  14. package/dist/source/loader/load_nodeset2.js.map +1 -1
  15. package/dist/source/xml_writer.d.ts +5 -0
  16. package/dist/src/base_node_private.js +5 -0
  17. package/dist/src/base_node_private.js.map +1 -1
  18. package/dist/src/index_current.d.ts +2 -1
  19. package/dist/src/index_current.js +3 -2
  20. package/dist/src/index_current.js.map +1 -1
  21. package/dist/src/namespace_impl.d.ts +2 -0
  22. package/dist/src/namespace_impl.js +11 -1
  23. package/dist/src/namespace_impl.js.map +1 -1
  24. package/dist/src/namespace_private.d.ts +1 -0
  25. package/dist/src/namespace_private.js.map +1 -1
  26. package/dist/src/nodeid_manager.d.ts +1 -0
  27. package/dist/src/nodeid_manager.js +14 -2
  28. package/dist/src/nodeid_manager.js.map +1 -1
  29. package/dist/src/nodeset_tools/dump_to_bsd.d.ts +2 -0
  30. package/dist/src/nodeset_tools/dump_to_bsd.js +164 -0
  31. package/dist/src/nodeset_tools/dump_to_bsd.js.map +1 -0
  32. package/dist/src/nodeset_tools/nodeset_to_xml.d.ts +9 -1
  33. package/dist/src/nodeset_tools/nodeset_to_xml.js +182 -87
  34. package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
  35. package/dist/src/tool_isSupertypeOf.js +12 -2
  36. package/dist/src/tool_isSupertypeOf.js.map +1 -1
  37. package/dist/src/ua_data_type_impl.js +10 -5
  38. package/dist/src/ua_data_type_impl.js.map +1 -1
  39. package/dist/src/ua_object_impl.js +8 -1
  40. package/dist/src/ua_object_impl.js.map +1 -1
  41. package/dist/src/ua_variable_impl.js +5 -1
  42. package/dist/src/ua_variable_impl.js.map +1 -1
  43. package/dist/src/ua_variable_impl_ext_obj.js +1 -1
  44. package/dist/src/ua_variable_impl_ext_obj.js.map +1 -1
  45. package/distHelpers/get_mini_address_space.js +1 -1
  46. package/distHelpers/get_mini_address_space.js.map +1 -1
  47. package/distNodeJS/generate_address_space.d.ts +3 -1
  48. package/distNodeJS/generate_address_space.js +13 -2
  49. package/distNodeJS/generate_address_space.js.map +1 -1
  50. package/package.json +38 -38
  51. package/source/continuation_points/continuation_point_manager.ts +13 -12
  52. package/source/index.ts +1 -0
  53. package/source/loader/ensure_datatype_extracted.ts +38 -3
  54. package/source/loader/generateAddressSpaceRaw.ts +4 -3
  55. package/source/loader/load_nodeset2.ts +86 -33
  56. package/source/xml_writer.ts +3 -0
  57. package/source_nodejs/generate_address_space.ts +27 -5
  58. package/src/base_node_private.ts +6 -0
  59. package/src/index_current.ts +3 -1
  60. package/src/namespace_impl.ts +24 -1
  61. package/src/namespace_private.ts +2 -0
  62. package/src/nodeid_manager.ts +14 -5
  63. package/src/nodeset_tools/{typedictionary_to_xml.ts → dump_to_bsd.ts} +24 -14
  64. package/src/nodeset_tools/nodeset_to_xml.ts +231 -74
  65. package/src/tool_isSupertypeOf.ts +14 -2
  66. package/src/ua_data_type_impl.ts +11 -7
  67. package/src/ua_object_impl.ts +12 -2
  68. package/src/ua_variable_impl.ts +9 -2
  69. package/src/ua_variable_impl_ext_obj.ts +1 -1
  70. package/test_helpers/get_mini_address_space.ts +1 -1
  71. package/test_helpers/test_fixtures/mini.Node.Set2.xml +29 -0
  72. package/test_helpers/test_fixtures/nodeset_no_aliases.xml +30 -0
  73. package/test_helpers/test_fixtures/nodeset_no_aliases_with_aliases.xml +31 -0
@@ -1,8 +1,10 @@
1
+ /* eslint-disable complexity */
1
2
  /**
2
3
  * @module node-opcua-address-space
3
4
  */
4
5
  // produce nodeset xml files
5
6
  import { assert } from "node-opcua-assert";
7
+ import { ObjectIds } from "node-opcua-constants";
6
8
  import { make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
7
9
  import { ExtensionObject } from "node-opcua-extension-object";
8
10
  import {
@@ -29,7 +31,7 @@ import {
29
31
  UAVariable,
30
32
  UAVariableType
31
33
  } from "node-opcua-address-space-base";
32
- import { Int64, minOPCUADate, StatusCode } from "node-opcua-basic-types";
34
+ import { AttributeIds, Int64, minOPCUADate, StatusCode, StatusCodes } from "node-opcua-basic-types";
33
35
  import { BrowseDescription, EnumDefinition, StructureDefinition, StructureType } from "node-opcua-types";
34
36
 
35
37
  import { XmlWriter } from "../../source/xml_writer";
@@ -44,6 +46,7 @@ import { NamespaceImpl } from "../namespace_impl";
44
46
  import { UAMethodImpl } from "../ua_method_impl";
45
47
  import { UADataTypeImpl } from "../ua_data_type_impl";
46
48
  import { UAVariableTypeImpl } from "../ua_variable_type_impl";
49
+ import { SessionContext } from "../index_current";
47
50
 
48
51
  import { DefinitionMap2, TypeInfo } from "../../source/loader/make_xml_extension_object_parser";
49
52
  import { makeDefinitionMap } from "../../source/loader/decode_xml_extension_object";
@@ -95,6 +98,12 @@ function b(xw: XmlWriter, browseName: QualifiedName): string {
95
98
  return translateBrowseName(xw, browseName).toString().replace("ns=0;", "");
96
99
  }
97
100
 
101
+ function _dumpReverseReferences(xw: XmlWriter, node: BaseNode) {
102
+
103
+ const addressSpace = node.addressSpace;
104
+ const hasSubtypeReferenceType = addressSpace.findReferenceType("HasSubtype")!;
105
+
106
+ }
98
107
  function _dumpReferences(xw: XmlWriter, node: BaseNode) {
99
108
  xw.startElement("References");
100
109
 
@@ -207,9 +216,53 @@ function _dumpXmlElement(xw: XmlWriter, v: string) {
207
216
  </uax:Body>
208
217
  </uax:ExtensionObject>
209
218
  */
219
+ type XmlNamespaceUri = string;
220
+ type XmlNs = string;
221
+ interface XmlWriterEx extends XmlWriter {
222
+ map: Record<XmlNamespaceUri, XmlNs>;
223
+ stackMap: Record<XmlNamespaceUri, XmlNs>[];
224
+ }
225
+ function initXmlWriterEx(xw: XmlWriter, map: Record<XmlNamespaceUri, XmlNs>): void {
226
+ const xwe = xw as XmlWriterEx;
227
+ xwe.map = map;
228
+ xwe.stackMap = [];
229
+ }
230
+
231
+ function getPrefix(xw: XmlWriter, namespace: XmlNamespaceUri): XmlNs {
232
+ const xwe = xw as XmlWriterEx;
233
+ if (!xwe.map) return "";
234
+ const p = xwe.map[namespace] || "";
235
+ return p ? p + ":" : "";
236
+ }
237
+
238
+ function restoreDefaultNamespace(xw: XmlWriter) {
239
+ const xwe = xw as XmlWriterEx;
240
+ if (!xwe.map) return;
241
+ xwe.map = xwe.stackMap.pop()!;
242
+ }
243
+
244
+ function setDefaultNamespace(xw: XmlWriter, namespace: XmlNamespaceUri): void {
245
+ const xwe = xw as XmlWriterEx;
246
+ if (!xwe.map) return;
247
+ if (xwe.map[namespace] !== "") {
248
+ xw.writeAttribute("xmlns", namespace);
249
+ }
250
+
251
+ xwe.stackMap.push({
252
+ ...xwe.map
253
+ });
254
+ xwe.map[namespace] = "";
255
+ }
256
+
257
+ function startElementEx(xw: XmlWriter, ns: XmlNs, name: string, defaultNamespace: XmlNamespaceUri) {
258
+ const xwe = xw as XmlWriterEx;
259
+ xw.startElement(name);
260
+ setDefaultNamespace(xw, defaultNamespace);
261
+ }
210
262
 
211
263
  function _dumpNodeId(xw: XmlWriter, v: NodeId) {
212
- xw.startElement("Identifier");
264
+ const xmlns = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
265
+ xw.startElement(`${xmlns}Identifier`);
213
266
  xw.text(n(xw, v));
214
267
  xw.endElement();
215
268
  }
@@ -224,7 +277,8 @@ function _dumpVariantValue(xw: XmlWriter, dataType: DataType, node: UAVariable |
224
277
  if (dataType === DataType.Null) {
225
278
  return;
226
279
  }
227
- xw.startElement(DataType[dataType]);
280
+ const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
281
+ xw.startElement(`${uax}${DataType[dataType]}`);
228
282
  const definitionMap = makeDefinitionMap(node.addressSpace);
229
283
  _dumpVariantInnerValue(xw, dataType, dataTypeNode.nodeId, definitionMap, value);
230
284
  xw.endElement();
@@ -306,6 +360,7 @@ function _dumpVariantInnerValue(
306
360
  definitionMap: DefinitionMap2,
307
361
  value: any
308
362
  ): void {
363
+ const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
309
364
  switch (dataType) {
310
365
  case null:
311
366
  case DataType.Null:
@@ -347,12 +402,12 @@ function _dumpVariantInnerValue(
347
402
  case DataType.Guid:
348
403
  /*
349
404
  <uax:Guid>
350
- <uax:String>947c29a7-490d-4dc9-adda-1109e3e8fcb7</uax:String>
405
+ <uax:String>947c29a7-490d-4dc9-adda-1109e3e8fcb7</uax:String>
351
406
  </uax:Guid>
352
407
  */
353
408
  if (value !== undefined && value !== null) {
354
409
  // xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2008/02/Types.xsd");
355
- xw.startElement("String");
410
+ xw.startElement(`${uax}String`);
356
411
  xw.text(value.toString());
357
412
  xw.endElement();
358
413
  }
@@ -406,24 +461,31 @@ function _dumpVariantExtensionObjectValue(
406
461
  // const encodingDefaultXml = (getStructureTypeConstructor(schema.name) as any).encodingDefaultXml;
407
462
  const encodingDefaultXml = value.schema.encodingDefaultXml;
408
463
  if (!encodingDefaultXml) {
464
+ warningLog("dataType Name ", name, "with ", dataTypeNodeId.toString(), " does not have xml encoding");
409
465
  // throw new Error("Extension Object doesn't provide a XML ");
410
466
  return;
411
467
  }
412
- xw.startElement("ExtensionObject");
468
+ const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
469
+ startElementEx(xw, uax, `ExtensionObject`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
413
470
  {
414
- xw.startElement("TypeId");
471
+ const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
472
+ xw.startElement(`${uax}TypeId`);
415
473
  {
416
474
  // find HasEncoding node
417
475
  // xx var encodingDefaultXml = schema.encodingDefaultXml;
418
- xw.startElement("Identifier");
476
+ xw.startElement(`${uax}Identifier`);
419
477
  xw.text(n(xw, encodingDefaultXml));
420
478
  xw.endElement();
421
479
  }
422
480
  xw.endElement();
423
- xw.startElement("Body");
481
+ startElementEx(xw, uax, "Body", "http://opcfoundation.org/UA/2008/02/Types.xsd");
482
+
424
483
  _dumpVariantExtensionObjectValue_Body(xw, definitionMap, name, definition as StructureDefinition, value);
484
+
485
+ restoreDefaultNamespace(xw);
425
486
  xw.endElement();
426
487
  }
488
+ restoreDefaultNamespace(xw);
427
489
  xw.endElement();
428
490
  }
429
491
 
@@ -454,10 +516,7 @@ function _isDefaultValue(value: Variant): boolean {
454
516
  }
455
517
  break;
456
518
  case DataType.Boolean:
457
- if (!value.value) {
458
- return true;
459
- }
460
- break;
519
+ return false; // we want it all the time !
461
520
  case DataType.SByte:
462
521
  case DataType.Byte:
463
522
  case DataType.UInt16:
@@ -512,7 +571,7 @@ function _dumpValue(xw: XmlWriter, node: UAVariable | UAVariableType, value: Var
512
571
  }
513
572
  assert(value instanceof Variant);
514
573
 
515
- const dataTypeNode = addressSpace.findNode(node.dataType);
574
+ const dataTypeNode = addressSpace.findDataType(node.dataType);
516
575
  if (!dataTypeNode) {
517
576
  console.log("Cannot find dataType:", node.dataType);
518
577
  return;
@@ -533,17 +592,14 @@ function _dumpValue(xw: XmlWriter, node: UAVariable | UAVariableType, value: Var
533
592
  }
534
593
  xw.startElement("Value");
535
594
 
595
+ const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
536
596
  if (isExtensionObject) {
537
- const dataTypeNode = addressSpace.findDataType(node.dataType);
538
- if (!dataTypeNode) {
539
- throw new Error("Cannot find data type " + node.dataType.toString());
540
- }
541
-
542
597
  const encodeXml = _dumpVariantExtensionObjectValue2.bind(null, xw, dataTypeNode);
543
598
 
544
599
  if (value.arrayType === VariantArrayType.Array) {
545
- xw.startElement("ListOf" + baseDataTypeName);
600
+ startElementEx(xw, uax, `ListOf${baseDataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
546
601
  value.value.forEach(encodeXml);
602
+ restoreDefaultNamespace(xw);
547
603
  xw.endElement();
548
604
  } else if (value.arrayType === VariantArrayType.Scalar) {
549
605
  encodeXml(value.value);
@@ -556,14 +612,14 @@ function _dumpValue(xw: XmlWriter, node: UAVariable | UAVariableType, value: Var
556
612
  const encodeXml = _dumpVariantValue.bind(null, xw, value.dataType, node);
557
613
  if (value.arrayType === VariantArrayType.Matrix) {
558
614
  // console.log("Warning _dumpValue : Matrix not supported yet");
559
- xw.startElement("ListOf" + dataTypeName);
560
- xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2008/02/Types.xsd");
615
+ startElementEx(xw, uax, `ListOf${dataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
561
616
  value.value.forEach(encodeXml);
617
+ restoreDefaultNamespace(xw);
562
618
  xw.endElement();
563
619
  } else if (value.arrayType === VariantArrayType.Array) {
564
- xw.startElement("ListOf" + dataTypeName);
565
- xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2008/02/Types.xsd");
620
+ startElementEx(xw, uax, `ListOf${dataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
566
621
  value.value.forEach(encodeXml);
622
+ restoreDefaultNamespace(xw);
567
623
  xw.endElement();
568
624
  } else if (value.arrayType === VariantArrayType.Scalar) {
569
625
  encodeXml(value.value);
@@ -586,12 +642,10 @@ function _dumpArrayDimensionsAttribute(xw: XmlWriter, node: UAVariableType | UAV
586
642
  }
587
643
  }
588
644
 
589
- function visitUANode(node: BaseNode, options: any, forward: boolean) {
645
+ function visitUANode(node: BaseNode, data: DumpData, forward: boolean) {
590
646
  assert(typeof forward === "boolean");
591
647
 
592
648
  const addressSpace = node.addressSpace;
593
- options.elements = options.elements || [];
594
- options.index_el = options.index_el || {};
595
649
 
596
650
  // visit references
597
651
  function process_reference(reference: UAReference) {
@@ -604,18 +658,18 @@ function visitUANode(node: BaseNode, options: any, forward: boolean) {
604
658
  return; // skip OPCUA namespace
605
659
  }
606
660
  const k = _hash(reference);
607
- if (!options.index_el[k]) {
608
- options.index_el[k] = 1;
661
+ if (!data.index_el[k]) {
662
+ data.index_el[k] = 1;
609
663
 
610
664
  const o = addressSpace.findNode(k)! as BaseNode;
611
665
  if (o) {
612
- visitUANode(o, options, forward);
666
+ visitUANode(o, data, forward);
613
667
  }
614
668
  }
615
669
  }
616
670
 
617
671
  (node as BaseNodeImpl).ownReferences().forEach(process_reference);
618
- options.elements.push(node);
672
+ data.elements.push(node as BaseNodeImpl);
619
673
  return node;
620
674
  }
621
675
 
@@ -682,11 +736,22 @@ function dumpReferencedNodes(xw: XmlWriter, node: BaseNode, forward: boolean) {
682
736
  }
683
737
  }
684
738
 
739
+ function getParent(node: BaseNode): BaseNode | null {
740
+ if (node instanceof UAVariableImpl || node instanceof UAMethodImpl || node instanceof UAObjectImpl) {
741
+ return node.parent;
742
+ }
743
+ return null;
744
+ }
745
+
685
746
  const currentReadFlag = makeAccessLevelFlag("CurrentRead");
686
747
  function dumpCommonAttributes(xw: XmlWriter, node: BaseNode) {
687
748
  xw.writeAttribute("NodeId", n(xw, node.nodeId));
688
749
  xw.writeAttribute("BrowseName", b(xw, node.browseName));
689
750
 
751
+ const parentNode = getParent(node);
752
+ if (parentNode) {
753
+ xw.writeAttribute("ParentNodeId", n(xw, parentNode.nodeId));
754
+ }
690
755
  if (Object.prototype.hasOwnProperty.call(node, "symbolicName")) {
691
756
  xw.writeAttribute("SymbolicName", (node as any).symbolicName);
692
757
  }
@@ -779,13 +844,20 @@ function _dumpStructureDefinition(
779
844
  }
780
845
  }
781
846
 
847
+ function _dumpEncoding(xw: XmlWriter, uaEncoding: UAObject) {
848
+ const uaDescription = uaEncoding.findReferencesAsObject("HasDescription")[0];
849
+ if (uaDescription) {
850
+ dumpUAVariable(xw, uaDescription as UAVariable);
851
+ }
852
+ _dumpUAObject(xw, uaEncoding);
853
+ }
782
854
  function _dumpEncodings(xw: XmlWriter, uaDataType: UADataType) {
783
855
  const encodings = uaDataType.findReferencesExAsObject("HasEncoding", BrowseDirection.Forward);
784
- for (const encoding of encodings) {
785
- if (encoding.nodeClass !== NodeClass.Object) {
856
+ for (const uaEncoding of encodings) {
857
+ if (uaEncoding.nodeClass !== NodeClass.Object) {
786
858
  continue;
787
859
  }
788
- _dumpUAObject(xw, encoding as UAObject);
860
+ _dumpEncoding(xw, uaEncoding as UAObject);
789
861
  }
790
862
  }
791
863
  function _dumpUADataTypeDefinition(xw: XmlWriter, uaDataType: UADataType) {
@@ -798,16 +870,24 @@ function _dumpUADataTypeDefinition(xw: XmlWriter, uaDataType: UADataType) {
798
870
  xw.endElement();
799
871
  return;
800
872
  }
873
+
801
874
  if (uaDataType.isStructure()) {
802
- const definition = uaDataType.getStructureDefinition();
803
- const baseDefinition = uaDataTypeBase ? uaDataTypeBase.getStructureDefinition() : null;
804
- xw.startElement("Definition");
805
- xw.writeAttribute("Name", b(xw, uaDataType.browseName));
806
- if (definition.structureType === StructureType.Union) {
807
- xw.writeAttribute("IsUnion", "true");
875
+ // in case the namespace is conforming to 1.03 specification the DataTypeDefinition attribute
876
+ // will be not be readable....
877
+
878
+ const dataValue = uaDataType.readAttribute(SessionContext.defaultContext, AttributeIds.DataTypeDefinition);
879
+
880
+ if (dataValue.statusCode === StatusCodes.Good) {
881
+ const definition = uaDataType.getStructureDefinition();
882
+ const baseDefinition = uaDataTypeBase ? uaDataTypeBase.getStructureDefinition() : null;
883
+ xw.startElement("Definition");
884
+ xw.writeAttribute("Name", b(xw, uaDataType.browseName));
885
+ if (definition.structureType === StructureType.Union) {
886
+ xw.writeAttribute("IsUnion", "true");
887
+ }
888
+ _dumpStructureDefinition(xw, definition, baseDefinition);
889
+ xw.endElement();
808
890
  }
809
- _dumpStructureDefinition(xw, definition, baseDefinition);
810
- xw.endElement();
811
891
  return;
812
892
  }
813
893
  }
@@ -845,6 +925,10 @@ function _markAsVisited(xw: XmlWriter, node: BaseNode) {
845
925
  }
846
926
 
847
927
  function dumpUAVariable(xw: XmlWriter, node: UAVariable) {
928
+ assert(node.nodeClass === NodeClass.Variable);
929
+ if (xw.visitedNode[_hash(node)]) {
930
+ return;
931
+ }
848
932
  _markAsVisited(xw, node);
849
933
 
850
934
  dumpReferencedNodes(xw, node, false);
@@ -886,6 +970,7 @@ function dumpUAVariable(xw: XmlWriter, node: UAVariable) {
886
970
  }
887
971
 
888
972
  function dumpUAVariableType(xw: XmlWriter, node: UAVariableType) {
973
+ assert(node.nodeClass === NodeClass.VariableType);
889
974
  xw.visitedNode = xw.visitedNode || {};
890
975
  assert(!xw.visitedNode[_hash(node)]);
891
976
  xw.visitedNode[_hash(node)] = 1;
@@ -942,6 +1027,7 @@ function dumpUAObject(xw: XmlWriter, node: UAObject) {
942
1027
  xw.writeComment("Object - " + b(xw, node.browseName) + " }}}} ");
943
1028
  }
944
1029
  function _dumpUAObject(xw: XmlWriter, node: UAObject) {
1030
+ assert(node.nodeClass === NodeClass.Object);
945
1031
  xw.visitedNode = xw.visitedNode || {};
946
1032
  assert(!xw.visitedNode[_hash(node)]);
947
1033
  xw.visitedNode[_hash(node)] = 1;
@@ -994,6 +1080,7 @@ function dumpAggregates(xw: XmlWriter, node: BaseNode) {
994
1080
  }
995
1081
 
996
1082
  function dumpUAObjectType(xw: XmlWriter, node: UAObjectTypeImpl) {
1083
+ assert(node.nodeClass === NodeClass.ObjectType);
997
1084
  assert(node instanceof UAObjectTypeImpl);
998
1085
  xw.writeComment("ObjectType - " + b(xw, node.browseName) + " {{{{ ");
999
1086
  _markAsVisited(xw, node);
@@ -1012,6 +1099,7 @@ function dumpUAObjectType(xw: XmlWriter, node: UAObjectTypeImpl) {
1012
1099
  }
1013
1100
 
1014
1101
  function dumpUAMethod(xw: XmlWriter, node: UAMethod) {
1102
+ assert(node.nodeClass === NodeClass.Method);
1015
1103
  _markAsVisited(xw, node);
1016
1104
 
1017
1105
  dumpReferencedNodes(xw, node, false);
@@ -1043,18 +1131,17 @@ function resolveDataTypeName(addressSpace: IAddressSpace, dataType: string | Nod
1043
1131
  return dataTypeNode.browseName;
1044
1132
  }
1045
1133
 
1046
- function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
1134
+ function buildUpAliases(node: BaseNode, xw: XmlWriter, data: BuildAliasesData) {
1047
1135
  const addressSpace = node.addressSpace;
1048
1136
 
1049
- options.aliases = options.aliases || {};
1050
- options.aliases_visited = options.aliases_visited || {};
1137
+ if (!data.aliases_visited) data.aliases_visited = {};
1051
1138
 
1052
1139
  const k = _hash(node);
1053
1140
  // istanbul ignore next
1054
- if (options.aliases_visited[k]) {
1141
+ if (data.aliases_visited[k]) {
1055
1142
  return;
1056
1143
  }
1057
- options.aliases_visited[k] = 1;
1144
+ data.aliases_visited[k] = 1;
1058
1145
 
1059
1146
  // put datatype into aliases list
1060
1147
  if (node.nodeClass === NodeClass.Variable || node.nodeClass === NodeClass.VariableType) {
@@ -1064,8 +1151,8 @@ function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
1064
1151
  // name
1065
1152
  const dataTypeName = b(xw, resolveDataTypeName(addressSpace, nodeV.dataType));
1066
1153
  if (dataTypeName) {
1067
- if (!options.aliases[dataTypeName]) {
1068
- options.aliases[dataTypeName] = n(xw, nodeV.dataType);
1154
+ if (!data.aliases[dataTypeName]) {
1155
+ data.aliases[dataTypeName] = n(xw, nodeV.dataType);
1069
1156
  }
1070
1157
  }
1071
1158
  }
@@ -1074,8 +1161,8 @@ function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
1074
1161
  // name
1075
1162
  const dataTypeName = b(xw, resolveDataTypeName(addressSpace, nodeV.dataType));
1076
1163
  if (dataTypeName) {
1077
- if (!options.aliases[dataTypeName]) {
1078
- options.aliases[dataTypeName] = n(xw, nodeV.dataType);
1164
+ if (!data.aliases[dataTypeName]) {
1165
+ data.aliases[dataTypeName] = n(xw, nodeV.dataType);
1079
1166
  }
1080
1167
  }
1081
1168
  }
@@ -1084,11 +1171,11 @@ function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
1084
1171
  function collectReferenceNameInAlias(reference: UAReference) {
1085
1172
  // reference.referenceType
1086
1173
  const key = b(xw, getReferenceType(reference).browseName);
1087
- if (!options.aliases.key) {
1174
+ if (!data.aliases.key) {
1088
1175
  if (reference.referenceType.namespace === 0) {
1089
- options.aliases[key] = reference.referenceType.toString().replace("ns=0;", "");
1176
+ data.aliases[key] = reference.referenceType.toString().replace("ns=0;", "");
1090
1177
  } else {
1091
- options.aliases[key] = n(xw, reference.referenceType);
1178
+ data.aliases[key] = n(xw, reference.referenceType);
1092
1179
  }
1093
1180
  }
1094
1181
  }
@@ -1096,7 +1183,7 @@ function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
1096
1183
  node.allReferences().forEach(collectReferenceNameInAlias);
1097
1184
  }
1098
1185
 
1099
- function writeAliases(xw: XmlWriter, aliases: any) {
1186
+ function writeAliases(xw: XmlWriter, aliases: Record<string, NodeIdString>) {
1100
1187
  xw.startElement("Aliases");
1101
1188
 
1102
1189
  if (aliases) {
@@ -1154,11 +1241,29 @@ function sortByNodeId(a: { nodeId: NodeId }, b: { nodeId: NodeId }) {
1154
1241
  return a.nodeId.toString() < b.nodeId.toString() ? -1 : 1;
1155
1242
  }
1156
1243
 
1157
- export function dumpXml(node: BaseNode, options: any): void {
1244
+ interface Dumpable {
1245
+ dumpXML(xw: typeof XMLWriter): void;
1246
+ }
1247
+ type NodeIdString = string;
1248
+
1249
+ export interface BuildAliasesData {
1250
+ aliases: Record<string, NodeIdString>;
1251
+ aliases_visited?: Record<string, unknown>;
1252
+ }
1253
+ interface DumpData extends BuildAliasesData {
1254
+ elements: Dumpable[];
1255
+ index_el: Record<string, number>;
1256
+ }
1257
+
1258
+ export interface DumpXMLOptions {
1259
+ /** */
1260
+ }
1261
+
1262
+ export function dumpXml(node: BaseNode, options: DumpXMLOptions): void {
1158
1263
  const namespace = node.namespace as NamespacePrivate;
1159
1264
 
1160
1265
  // make a first visit so that we determine which node to output and in which order
1161
- const nodesToVisit: any = {};
1266
+ const data: DumpData = { aliases: {}, aliases_visited: {}, index_el: {}, elements: [] };
1162
1267
 
1163
1268
  const dependency = constructNamespaceDependency(namespace);
1164
1269
  const translationTable = constructNamespaceTranslationTable(dependency);
@@ -1166,7 +1271,7 @@ export function dumpXml(node: BaseNode, options: any): void {
1166
1271
  const xw = new XMLWriter(true);
1167
1272
  xw.translationTable = translationTable;
1168
1273
 
1169
- visitUANode(node, nodesToVisit, false);
1274
+ visitUANode(node, data, false);
1170
1275
 
1171
1276
  xw.startDocument({ encoding: "utf-8" });
1172
1277
  xw.startElement("UANodeSet");
@@ -1176,10 +1281,26 @@ export function dumpXml(node: BaseNode, options: any): void {
1176
1281
  xw.writeAttribute("LastModified", new Date().toISOString());
1177
1282
  xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd");
1178
1283
 
1179
- buildUpAliases(node, xw, nodesToVisit);
1180
- writeAliases(xw, nodesToVisit.aliases);
1284
+ buildUpAliases(node, xw, data);
1285
+ writeAliases(xw, data.aliases);
1286
+
1287
+ const xmlNamspace = {
1288
+ default: { namespace: "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd" }
1289
+ };
1181
1290
 
1182
- for (const el of nodesToVisit.elements) {
1291
+ xw.startElement("Extensions");
1292
+ {
1293
+ xw.startElement("Extension");
1294
+ {
1295
+ xw.startElement("ModelInfo");
1296
+ xw.writeAttribute("NodeOPCUA");
1297
+ xw.endElement();
1298
+ }
1299
+ xw.endElement();
1300
+ }
1301
+ xw.endElement();
1302
+
1303
+ for (const el of data.elements!) {
1183
1304
  el.dumpXML(xw);
1184
1305
  }
1185
1306
 
@@ -1231,6 +1352,12 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1231
1352
  // ------------- INamespace Uris
1232
1353
  xw.startElement("NamespaceUris");
1233
1354
 
1355
+ initXmlWriterEx(xw, {
1356
+ "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd": "",
1357
+ "http://opcfoundation.org/UA/2008/02/Types.xsd": "uax",
1358
+ "http://www.w3.org/2001/XMLSchema-instance": "xsi"
1359
+ });
1360
+
1234
1361
  // xx const namespaceArray = namespace.addressSpace.getNamespaceArray();
1235
1362
  for (const depend of dependency) {
1236
1363
  if (depend.index === 0) {
@@ -1264,11 +1391,11 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1264
1391
  }
1265
1392
  xw.endElement();
1266
1393
 
1267
- const s: any = {};
1394
+ const data: BuildAliasesData = { aliases: {} };
1268
1395
  for (const node of this.nodeIterator()) {
1269
- buildUpAliases(node, xw, s);
1396
+ buildUpAliases(node, xw, data);
1270
1397
  }
1271
- writeAliases(xw, s.aliases);
1398
+ writeAliases(xw, data.aliases);
1272
1399
 
1273
1400
  xw.visitedNode = {};
1274
1401
 
@@ -1281,10 +1408,8 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1281
1408
 
1282
1409
  // -------------- Dictionaries
1283
1410
  const addressSpace = this.addressSpace;
1284
- const opcBinaryTypeSystem = addressSpace.findNode("OPCBinarySchema_TypeSystem") as UAObject;
1285
- if (opcBinaryTypeSystem) {
1286
- // let find all DataType dictionary node corresponding to a given namespace
1287
- // (have DataTypeDictionaryType)
1411
+
1412
+ const getDataTypeDescription = (opcBinaryTypeSystem: UAObject) => {
1288
1413
  const nodeToBrowse = new BrowseDescription({
1289
1414
  browseDirection: BrowseDirection.Forward,
1290
1415
  includeSubtypes: false,
@@ -1295,12 +1420,9 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1295
1420
  });
1296
1421
  const result = opcBinaryTypeSystem.browseNode(nodeToBrowse).filter((r) => r.nodeId.namespace === this.index);
1297
1422
  assert(result.length <= 1);
1298
- if (result.length === 1) {
1299
- xw.writeComment("DataSystem");
1300
- const dataSystemType = addressSpace.findNode(result[0].nodeId)! as UAVariable;
1301
- dumpNodeInXml(xw, dataSystemType);
1302
- }
1303
- }
1423
+ return result;
1424
+ };
1425
+
1304
1426
  // -------------- DataTypes
1305
1427
  const dataTypes = [...this._dataTypeIterator()].sort(sortByBrowseName);
1306
1428
  if (dataTypes.length) {
@@ -1311,7 +1433,42 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1311
1433
  dumpNodeInXml(xw, dataType);
1312
1434
  }
1313
1435
  }
1436
+
1437
+ // --------------
1438
+ const opcBinaryTypeSystem = addressSpace.findNode(ObjectIds.OPCBinarySchema_TypeSystem) as UAObject;
1439
+ const opcXmlSchemaTypeSystem = addressSpace.findNode(ObjectIds.XmlSchema_TypeSystem) as UAObject;
1440
+
1441
+ if (opcBinaryTypeSystem) {
1442
+ // let find all DataType dictionary node corresponding to a given namespace
1443
+ // (have DataTypeDictionaryType)
1444
+ const result = getDataTypeDescription(opcBinaryTypeSystem);
1445
+ if (result.length === 1) {
1446
+ xw.writeComment("DataSystem - Binary");
1447
+ const dataSystemType = addressSpace.findNode(result[0].nodeId)! as UAVariable;
1448
+ const types = dataSystemType.getComponents();
1449
+ for (const f of types) {
1450
+ dumpNodeInXml(xw, f);
1451
+ }
1452
+ dumpNodeInXml(xw, dataSystemType);
1453
+ }
1454
+ }
1455
+
1456
+ if (opcXmlSchemaTypeSystem) {
1457
+ const result = getDataTypeDescription(opcXmlSchemaTypeSystem);
1458
+ if (result.length === 1) {
1459
+ xw.writeComment("DataSystem - Xml");
1460
+ const dataSystemType = addressSpace.findNode(result[0].nodeId)! as UAVariable;
1461
+
1462
+ const types = dataSystemType.getComponents();
1463
+ for (const f of types) {
1464
+ dumpNodeInXml(xw, f);
1465
+ }
1466
+
1467
+ dumpNodeInXml(xw, dataSystemType);
1468
+ }
1469
+ }
1314
1470
  }
1471
+
1315
1472
  // -------------- ObjectTypes
1316
1473
  xw.writeComment("ObjectTypes");
1317
1474
  const objectTypes = [...this._objectTypeIterator()].sort(sortByBrowseName);
@@ -10,6 +10,7 @@ import { BaseNode, UADataType, UAObjectType, UAReference, UAReferenceType, UAVar
10
10
  import { BaseNode_getCache } from "./base_node_private";
11
11
  import { ReferenceImpl } from "./reference_impl";
12
12
  import { BaseNodeImpl } from "./base_node_impl";
13
+ import { NodeClass } from "node-opcua-data-model";
13
14
 
14
15
  const HasSubTypeNodeId = resolveNodeId("HasSubtype");
15
16
 
@@ -96,8 +97,19 @@ export type UAType = UAReferenceType | UADataType | UAObjectType | UAVariableTyp
96
97
 
97
98
  export function construct_isSupertypeOf<T extends UAType>(Class: typeof BaseNodeImpl): IsSupertypeOfFunc<T> {
98
99
  return wrap_memoize(function (this: T, baseType: T | NodeIdLike): boolean {
99
- assert(baseType instanceof Class);
100
- assert(this instanceof Class);
100
+ if (!(baseType instanceof Class)) {
101
+ throw new Error(
102
+ "expecting baseType to be " +
103
+ Class.name +
104
+ " but got " +
105
+ baseType.constructor.name +
106
+ " " +
107
+ NodeClass[(baseType as BaseNode).nodeClass]
108
+ );
109
+ }
110
+ if (!(this instanceof Class)) {
111
+ throw new Error("expecting this to be " + Class.name + " but got " + baseType.constructor.name);
112
+ }
101
113
  return _slow_isSupertypeOf.call(this, Class, baseType as T);
102
114
  }, hashBaseNode);
103
115
  }