node-opcua-address-space 2.77.0 → 2.79.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 (109) 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/alarms_and_conditions/ua_limit_alarm_impl.d.ts +1 -1
  17. package/dist/src/base_node_impl.d.ts +1 -0
  18. package/dist/src/base_node_impl.js +30 -3
  19. package/dist/src/base_node_impl.js.map +1 -1
  20. package/dist/src/base_node_private.js +5 -0
  21. package/dist/src/base_node_private.js.map +1 -1
  22. package/dist/src/historical_access/address_space_historical_data_node.js +14 -3
  23. package/dist/src/historical_access/address_space_historical_data_node.js.map +1 -1
  24. package/dist/src/index_current.d.ts +2 -1
  25. package/dist/src/index_current.js +3 -2
  26. package/dist/src/index_current.js.map +1 -1
  27. package/dist/src/namespace_impl.d.ts +2 -0
  28. package/dist/src/namespace_impl.js +11 -1
  29. package/dist/src/namespace_impl.js.map +1 -1
  30. package/dist/src/namespace_private.d.ts +1 -0
  31. package/dist/src/namespace_private.js.map +1 -1
  32. package/dist/src/nodeid_manager.d.ts +1 -0
  33. package/dist/src/nodeid_manager.js +14 -2
  34. package/dist/src/nodeid_manager.js.map +1 -1
  35. package/dist/src/nodeset_tools/{typedictionary_to_xml.d.ts → dump_to_bsd.d.ts} +1 -1
  36. package/dist/src/nodeset_tools/{typedictionary_to_xml.js → dump_to_bsd.js} +14 -5
  37. package/dist/src/nodeset_tools/dump_to_bsd.js.map +1 -0
  38. package/dist/src/nodeset_tools/nodeset_to_xml.d.ts +9 -1
  39. package/dist/src/nodeset_tools/nodeset_to_xml.js +220 -89
  40. package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
  41. package/dist/src/tool_isSupertypeOf.js +12 -2
  42. package/dist/src/tool_isSupertypeOf.js.map +1 -1
  43. package/dist/src/ua_data_type_impl.js +10 -5
  44. package/dist/src/ua_data_type_impl.js.map +1 -1
  45. package/dist/src/ua_method_impl.d.ts +2 -1
  46. package/dist/src/ua_method_impl.js +9 -1
  47. package/dist/src/ua_method_impl.js.map +1 -1
  48. package/dist/src/ua_object_impl.js +8 -1
  49. package/dist/src/ua_object_impl.js.map +1 -1
  50. package/dist/src/ua_variable_impl.d.ts +5 -0
  51. package/dist/src/ua_variable_impl.js +36 -2
  52. package/dist/src/ua_variable_impl.js.map +1 -1
  53. package/dist/src/ua_variable_impl_ext_obj.js +1 -1
  54. package/dist/src/ua_variable_impl_ext_obj.js.map +1 -1
  55. package/distHelpers/get_mini_address_space.js +1 -1
  56. package/distHelpers/get_mini_address_space.js.map +1 -1
  57. package/distNodeJS/generate_address_space.d.ts +3 -1
  58. package/distNodeJS/generate_address_space.js +13 -2
  59. package/distNodeJS/generate_address_space.js.map +1 -1
  60. package/package.json +26 -26
  61. package/source/continuation_points/continuation_point_manager.ts +13 -12
  62. package/source/index.ts +1 -0
  63. package/source/loader/ensure_datatype_extracted.ts +38 -3
  64. package/source/loader/generateAddressSpaceRaw.ts +4 -3
  65. package/source/loader/load_nodeset2.ts +86 -33
  66. package/source/xml_writer.ts +3 -0
  67. package/source_nodejs/generate_address_space.ts +27 -5
  68. package/src/alarms_and_conditions/ua_limit_alarm_impl.ts +1 -1
  69. package/src/base_node_impl.ts +34 -3
  70. package/src/base_node_private.ts +6 -0
  71. package/src/historical_access/address_space_historical_data_node.ts +18 -3
  72. package/src/index_current.ts +3 -1
  73. package/src/namespace_impl.ts +24 -1
  74. package/src/namespace_private.ts +2 -0
  75. package/src/nodeid_manager.ts +14 -5
  76. package/src/nodeset_tools/{typedictionary_to_xml.ts → dump_to_bsd.ts} +24 -14
  77. package/src/nodeset_tools/nodeset_to_xml.ts +278 -77
  78. package/src/tool_isSupertypeOf.ts +14 -2
  79. package/src/ua_data_type_impl.ts +11 -7
  80. package/src/ua_method_impl.ts +9 -3
  81. package/src/ua_object_impl.ts +12 -2
  82. package/src/ua_variable_impl.ts +42 -4
  83. package/src/ua_variable_impl_ext_obj.ts +1 -1
  84. package/test_helpers/get_mini_address_space.ts +1 -1
  85. package/test_helpers/test_fixtures/mini.Node.Set2.xml +207 -0
  86. package/test_helpers/test_fixtures/nodeset_no_aliases.xml +30 -0
  87. package/test_helpers/test_fixtures/nodeset_no_aliases_with_aliases.xml +31 -0
  88. package/dist/source/helpers/check_event_clause.d.ts +0 -17
  89. package/dist/source/helpers/check_event_clause.js +0 -53
  90. package/dist/source/helpers/check_event_clause.js.map +0 -1
  91. package/dist/src/alarms_and_conditions/check_where_clause.d.ts +0 -4
  92. package/dist/src/alarms_and_conditions/check_where_clause.js +0 -110
  93. package/dist/src/alarms_and_conditions/check_where_clause.js.map +0 -1
  94. package/dist/src/alarms_and_conditions/condition_info.d.ts +0 -27
  95. package/dist/src/alarms_and_conditions/condition_info.js +0 -55
  96. package/dist/src/alarms_and_conditions/condition_info.js.map +0 -1
  97. package/dist/src/alarms_and_conditions/condition_snapshot.d.ts +0 -233
  98. package/dist/src/alarms_and_conditions/condition_snapshot.js +0 -667
  99. package/dist/src/alarms_and_conditions/condition_snapshot.js.map +0 -1
  100. package/dist/src/alarms_and_conditions/extract_event_fields.d.ts +0 -10
  101. package/dist/src/alarms_and_conditions/extract_event_fields.js +0 -90
  102. package/dist/src/alarms_and_conditions/extract_event_fields.js.map +0 -1
  103. package/dist/src/data_access/ua_multistate_value_discrete.d.ts +0 -51
  104. package/dist/src/data_access/ua_multistate_value_discrete.js +0 -250
  105. package/dist/src/data_access/ua_multistate_value_discrete.js.map +0 -1
  106. package/dist/src/data_access/ua_two_state_discrete.d.ts +0 -25
  107. package/dist/src/data_access/ua_two_state_discrete.js +0 -154
  108. package/dist/src/data_access/ua_two_state_discrete.js.map +0 -1
  109. package/dist/src/nodeset_tools/typedictionary_to_xml.js.map +0 -1
@@ -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, VariableIds } 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 {
@@ -14,7 +16,7 @@ import {
14
16
  makeAccessLevelFlag,
15
17
  QualifiedName
16
18
  } from "node-opcua-data-model";
17
- import { NodeId, NodeIdType, resolveNodeId } from "node-opcua-nodeid";
19
+ import { ExpandedNodeId, NodeId, NodeIdType, resolveNodeId } from "node-opcua-nodeid";
18
20
  import * as utils from "node-opcua-utils";
19
21
  import { Variant, VariantArrayType, DataType } from "node-opcua-variant";
20
22
  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,10 @@ 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
+ const addressSpace = node.addressSpace;
103
+ const hasSubtypeReferenceType = addressSpace.findReferenceType("HasSubtype")!;
104
+ }
98
105
  function _dumpReferences(xw: XmlWriter, node: BaseNode) {
99
106
  xw.startElement("References");
100
107
 
@@ -207,9 +214,67 @@ function _dumpXmlElement(xw: XmlWriter, v: string) {
207
214
  </uax:Body>
208
215
  </uax:ExtensionObject>
209
216
  */
217
+ type XmlNamespaceUri = string;
218
+ type NamespaceUri = string;
219
+ type XmlNs = string;
220
+ interface XmlWriterEx extends XmlWriter {
221
+ map: Record<XmlNamespaceUri, XmlNs>;
222
+ stackMap: Record<XmlNamespaceUri, XmlNs>[];
223
+ namespaceArray: NamespaceUri[];
224
+ }
225
+ function initXmlWriterEx(xw: XmlWriter, map: Record<XmlNamespaceUri, XmlNs>, namespaceArray: NamespaceUri[]): void {
226
+ const xwe = xw as XmlWriterEx;
227
+ xwe.map = map;
228
+ xwe.stackMap = [];
229
+ xwe.namespaceArray = namespaceArray;
230
+ }
231
+ function findXsdNamespaceUri(xw: XmlWriter, nodeId: NodeId): string {
232
+ const xwe = xw as XmlWriterEx;
233
+ if (!xwe.namespaceArray) {
234
+ return "";
235
+ }
236
+ const namespace = xwe.namespaceArray[nodeId.namespace];
237
+ if (namespace === "http://opcfoundation.org/UA/") {
238
+ return "http://opcfoundation.org/UA/2008/02/Types.xsd";
239
+ }
240
+ return namespace.replace(/\/$/, "") + "/Types.xsd";
241
+ }
242
+
243
+ function getPrefix(xw: XmlWriter, namespace: XmlNamespaceUri): XmlNs {
244
+ const xwe = xw as XmlWriterEx;
245
+ if (!xwe.map) return "";
246
+ const p = xwe.map[namespace] || "";
247
+ return p ? p + ":" : "";
248
+ }
249
+
250
+ function restoreDefaultNamespace(xw: XmlWriter) {
251
+ const xwe = xw as XmlWriterEx;
252
+ if (!xwe.map) return;
253
+ xwe.map = xwe.stackMap.pop()!;
254
+ }
255
+
256
+ function setDefaultNamespace(xw: XmlWriter, namespace: XmlNamespaceUri): void {
257
+ const xwe = xw as XmlWriterEx;
258
+ if (!xwe.map) return;
259
+ if (xwe.map[namespace] !== "") {
260
+ xw.writeAttribute("xmlns", namespace);
261
+ }
262
+
263
+ xwe.stackMap.push({
264
+ ...xwe.map
265
+ });
266
+ xwe.map[namespace] = "";
267
+ }
268
+
269
+ function startElementEx(xw: XmlWriter, ns: XmlNs, name: string, defaultNamespace: XmlNamespaceUri) {
270
+ const xwe = xw as XmlWriterEx;
271
+ xw.startElement(name);
272
+ setDefaultNamespace(xw, defaultNamespace);
273
+ }
210
274
 
211
275
  function _dumpNodeId(xw: XmlWriter, v: NodeId) {
212
- xw.startElement("Identifier");
276
+ const xmlns = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
277
+ xw.startElement(`${xmlns}Identifier`);
213
278
  xw.text(n(xw, v));
214
279
  xw.endElement();
215
280
  }
@@ -224,7 +289,8 @@ function _dumpVariantValue(xw: XmlWriter, dataType: DataType, node: UAVariable |
224
289
  if (dataType === DataType.Null) {
225
290
  return;
226
291
  }
227
- xw.startElement(DataType[dataType]);
292
+ const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
293
+ xw.startElement(`${uax}${DataType[dataType]}`);
228
294
  const definitionMap = makeDefinitionMap(node.addressSpace);
229
295
  _dumpVariantInnerValue(xw, dataType, dataTypeNode.nodeId, definitionMap, value);
230
296
  xw.endElement();
@@ -236,6 +302,9 @@ function _dumpVariantInnerExtensionObject(
236
302
  definition: StructureDefinition,
237
303
  value: ExtensionObject
238
304
  ) {
305
+ const namespaceUri = findXsdNamespaceUri(xw, definition.defaultEncodingId);
306
+ const ns = getPrefix(xw, namespaceUri);
307
+
239
308
  for (const field of definition.fields || []) {
240
309
  const dataTypeNodeId = field.dataType;
241
310
 
@@ -251,8 +320,11 @@ function _dumpVariantInnerExtensionObject(
251
320
  // to do ?? shall we do a extension Object here ?
252
321
  continue; // ns=0;i=0 is reserved
253
322
  }
323
+
254
324
  const { name, definition } = definitionMap.findDefinition(dataTypeNodeId);
255
- xw.startElement(fieldName);
325
+
326
+ startElementEx(xw, ns, fieldName, namespaceUri);
327
+ // xw.startElement(fieldName);
256
328
 
257
329
  let fun: (value: any) => void = (value: any) => {
258
330
  /** */
@@ -285,6 +357,7 @@ function _dumpVariantInnerExtensionObject(
285
357
  console.log(field);
286
358
  // throw err;
287
359
  }
360
+ restoreDefaultNamespace(xw);
288
361
  xw.endElement();
289
362
  }
290
363
  }
@@ -306,6 +379,7 @@ function _dumpVariantInnerValue(
306
379
  definitionMap: DefinitionMap2,
307
380
  value: any
308
381
  ): void {
382
+ const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
309
383
  switch (dataType) {
310
384
  case null:
311
385
  case DataType.Null:
@@ -347,12 +421,12 @@ function _dumpVariantInnerValue(
347
421
  case DataType.Guid:
348
422
  /*
349
423
  <uax:Guid>
350
- <uax:String>947c29a7-490d-4dc9-adda-1109e3e8fcb7</uax:String>
424
+ <uax:String>947c29a7-490d-4dc9-adda-1109e3e8fcb7</uax:String>
351
425
  </uax:Guid>
352
426
  */
353
427
  if (value !== undefined && value !== null) {
354
428
  // xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2008/02/Types.xsd");
355
- xw.startElement("String");
429
+ xw.startElement(`${uax}String`);
356
430
  xw.text(value.toString());
357
431
  xw.endElement();
358
432
  }
@@ -388,10 +462,13 @@ function _dumpVariantExtensionObjectValue_Body(
388
462
  value: any
389
463
  ) {
390
464
  if (value) {
391
- xw.startElement(name);
465
+ const namespaceUri = findXsdNamespaceUri(xw, definition.defaultEncodingId);
466
+ const ns = getPrefix(xw, namespaceUri);
467
+ startElementEx(xw, ns, `${name}`, namespaceUri);
392
468
  if (value) {
393
469
  _dumpVariantInnerExtensionObject(xw, definitionMap, definition, value);
394
470
  }
471
+ restoreDefaultNamespace(xw);
395
472
  xw.endElement();
396
473
  }
397
474
  }
@@ -406,24 +483,31 @@ function _dumpVariantExtensionObjectValue(
406
483
  // const encodingDefaultXml = (getStructureTypeConstructor(schema.name) as any).encodingDefaultXml;
407
484
  const encodingDefaultXml = value.schema.encodingDefaultXml;
408
485
  if (!encodingDefaultXml) {
486
+ warningLog("dataType Name ", name, "with ", dataTypeNodeId.toString(), " does not have xml encoding");
409
487
  // throw new Error("Extension Object doesn't provide a XML ");
410
488
  return;
411
489
  }
412
- xw.startElement("ExtensionObject");
490
+ const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
491
+ startElementEx(xw, uax, `ExtensionObject`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
413
492
  {
414
- xw.startElement("TypeId");
493
+ const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
494
+ xw.startElement(`${uax}TypeId`);
415
495
  {
416
496
  // find HasEncoding node
417
497
  // xx var encodingDefaultXml = schema.encodingDefaultXml;
418
- xw.startElement("Identifier");
498
+ xw.startElement(`${uax}Identifier`);
419
499
  xw.text(n(xw, encodingDefaultXml));
420
500
  xw.endElement();
421
501
  }
422
502
  xw.endElement();
423
- xw.startElement("Body");
503
+ startElementEx(xw, uax, "Body", "http://opcfoundation.org/UA/2008/02/Types.xsd");
504
+
424
505
  _dumpVariantExtensionObjectValue_Body(xw, definitionMap, name, definition as StructureDefinition, value);
506
+
507
+ restoreDefaultNamespace(xw);
425
508
  xw.endElement();
426
509
  }
510
+ restoreDefaultNamespace(xw);
427
511
  xw.endElement();
428
512
  }
429
513
 
@@ -454,10 +538,7 @@ function _isDefaultValue(value: Variant): boolean {
454
538
  }
455
539
  break;
456
540
  case DataType.Boolean:
457
- if (!value.value) {
458
- return true;
459
- }
460
- break;
541
+ return false; // we want it all the time !
461
542
  case DataType.SByte:
462
543
  case DataType.Byte:
463
544
  case DataType.UInt16:
@@ -512,7 +593,7 @@ function _dumpValue(xw: XmlWriter, node: UAVariable | UAVariableType, value: Var
512
593
  }
513
594
  assert(value instanceof Variant);
514
595
 
515
- const dataTypeNode = addressSpace.findNode(node.dataType);
596
+ const dataTypeNode = addressSpace.findDataType(node.dataType);
516
597
  if (!dataTypeNode) {
517
598
  console.log("Cannot find dataType:", node.dataType);
518
599
  return;
@@ -533,17 +614,14 @@ function _dumpValue(xw: XmlWriter, node: UAVariable | UAVariableType, value: Var
533
614
  }
534
615
  xw.startElement("Value");
535
616
 
617
+ const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
536
618
  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
619
  const encodeXml = _dumpVariantExtensionObjectValue2.bind(null, xw, dataTypeNode);
543
620
 
544
621
  if (value.arrayType === VariantArrayType.Array) {
545
- xw.startElement("ListOf" + baseDataTypeName);
622
+ startElementEx(xw, uax, `ListOf${baseDataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
546
623
  value.value.forEach(encodeXml);
624
+ restoreDefaultNamespace(xw);
547
625
  xw.endElement();
548
626
  } else if (value.arrayType === VariantArrayType.Scalar) {
549
627
  encodeXml(value.value);
@@ -556,14 +634,14 @@ function _dumpValue(xw: XmlWriter, node: UAVariable | UAVariableType, value: Var
556
634
  const encodeXml = _dumpVariantValue.bind(null, xw, value.dataType, node);
557
635
  if (value.arrayType === VariantArrayType.Matrix) {
558
636
  // 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");
637
+ startElementEx(xw, uax, `ListOf${dataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
561
638
  value.value.forEach(encodeXml);
639
+ restoreDefaultNamespace(xw);
562
640
  xw.endElement();
563
641
  } else if (value.arrayType === VariantArrayType.Array) {
564
- xw.startElement("ListOf" + dataTypeName);
565
- xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2008/02/Types.xsd");
642
+ startElementEx(xw, uax, `ListOf${dataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
566
643
  value.value.forEach(encodeXml);
644
+ restoreDefaultNamespace(xw);
567
645
  xw.endElement();
568
646
  } else if (value.arrayType === VariantArrayType.Scalar) {
569
647
  encodeXml(value.value);
@@ -586,12 +664,10 @@ function _dumpArrayDimensionsAttribute(xw: XmlWriter, node: UAVariableType | UAV
586
664
  }
587
665
  }
588
666
 
589
- function visitUANode(node: BaseNode, options: any, forward: boolean) {
667
+ function visitUANode(node: BaseNode, data: DumpData, forward: boolean) {
590
668
  assert(typeof forward === "boolean");
591
669
 
592
670
  const addressSpace = node.addressSpace;
593
- options.elements = options.elements || [];
594
- options.index_el = options.index_el || {};
595
671
 
596
672
  // visit references
597
673
  function process_reference(reference: UAReference) {
@@ -604,18 +680,18 @@ function visitUANode(node: BaseNode, options: any, forward: boolean) {
604
680
  return; // skip OPCUA namespace
605
681
  }
606
682
  const k = _hash(reference);
607
- if (!options.index_el[k]) {
608
- options.index_el[k] = 1;
683
+ if (!data.index_el[k]) {
684
+ data.index_el[k] = 1;
609
685
 
610
686
  const o = addressSpace.findNode(k)! as BaseNode;
611
687
  if (o) {
612
- visitUANode(o, options, forward);
688
+ visitUANode(o, data, forward);
613
689
  }
614
690
  }
615
691
  }
616
692
 
617
693
  (node as BaseNodeImpl).ownReferences().forEach(process_reference);
618
- options.elements.push(node);
694
+ data.elements.push(node as BaseNodeImpl);
619
695
  return node;
620
696
  }
621
697
 
@@ -682,11 +758,22 @@ function dumpReferencedNodes(xw: XmlWriter, node: BaseNode, forward: boolean) {
682
758
  }
683
759
  }
684
760
 
761
+ function getParent(node: BaseNode): BaseNode | null {
762
+ if (node instanceof UAVariableImpl || node instanceof UAMethodImpl || node instanceof UAObjectImpl) {
763
+ return node.parent;
764
+ }
765
+ return null;
766
+ }
767
+
685
768
  const currentReadFlag = makeAccessLevelFlag("CurrentRead");
686
769
  function dumpCommonAttributes(xw: XmlWriter, node: BaseNode) {
687
770
  xw.writeAttribute("NodeId", n(xw, node.nodeId));
688
771
  xw.writeAttribute("BrowseName", b(xw, node.browseName));
689
772
 
773
+ const parentNode = getParent(node);
774
+ if (parentNode) {
775
+ xw.writeAttribute("ParentNodeId", n(xw, parentNode.nodeId));
776
+ }
690
777
  if (Object.prototype.hasOwnProperty.call(node, "symbolicName")) {
691
778
  xw.writeAttribute("SymbolicName", (node as any).symbolicName);
692
779
  }
@@ -779,13 +866,20 @@ function _dumpStructureDefinition(
779
866
  }
780
867
  }
781
868
 
869
+ function _dumpEncoding(xw: XmlWriter, uaEncoding: UAObject) {
870
+ const uaDescription = uaEncoding.findReferencesAsObject("HasDescription")[0];
871
+ if (uaDescription) {
872
+ dumpUAVariable(xw, uaDescription as UAVariable);
873
+ }
874
+ _dumpUAObject(xw, uaEncoding);
875
+ }
782
876
  function _dumpEncodings(xw: XmlWriter, uaDataType: UADataType) {
783
877
  const encodings = uaDataType.findReferencesExAsObject("HasEncoding", BrowseDirection.Forward);
784
- for (const encoding of encodings) {
785
- if (encoding.nodeClass !== NodeClass.Object) {
878
+ for (const uaEncoding of encodings) {
879
+ if (uaEncoding.nodeClass !== NodeClass.Object) {
786
880
  continue;
787
881
  }
788
- _dumpUAObject(xw, encoding as UAObject);
882
+ _dumpEncoding(xw, uaEncoding as UAObject);
789
883
  }
790
884
  }
791
885
  function _dumpUADataTypeDefinition(xw: XmlWriter, uaDataType: UADataType) {
@@ -798,16 +892,24 @@ function _dumpUADataTypeDefinition(xw: XmlWriter, uaDataType: UADataType) {
798
892
  xw.endElement();
799
893
  return;
800
894
  }
895
+
801
896
  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");
897
+ // in case the namespace is conforming to 1.03 specification the DataTypeDefinition attribute
898
+ // will be not be readable....
899
+
900
+ const dataValue = uaDataType.readAttribute(SessionContext.defaultContext, AttributeIds.DataTypeDefinition);
901
+
902
+ if (true || dataValue.statusCode === StatusCodes.Good) {
903
+ const definition = uaDataType.getStructureDefinition();
904
+ const baseDefinition = uaDataTypeBase ? uaDataTypeBase.getStructureDefinition() : null;
905
+ xw.startElement("Definition");
906
+ xw.writeAttribute("Name", b(xw, uaDataType.browseName));
907
+ if (definition.structureType === StructureType.Union) {
908
+ xw.writeAttribute("IsUnion", "true");
909
+ }
910
+ _dumpStructureDefinition(xw, definition, baseDefinition);
911
+ xw.endElement();
808
912
  }
809
- _dumpStructureDefinition(xw, definition, baseDefinition);
810
- xw.endElement();
811
913
  return;
812
914
  }
813
915
  }
@@ -845,6 +947,10 @@ function _markAsVisited(xw: XmlWriter, node: BaseNode) {
845
947
  }
846
948
 
847
949
  function dumpUAVariable(xw: XmlWriter, node: UAVariable) {
950
+ assert(node.nodeClass === NodeClass.Variable);
951
+ if (xw.visitedNode[_hash(node)]) {
952
+ return;
953
+ }
848
954
  _markAsVisited(xw, node);
849
955
 
850
956
  dumpReferencedNodes(xw, node, false);
@@ -886,6 +992,7 @@ function dumpUAVariable(xw: XmlWriter, node: UAVariable) {
886
992
  }
887
993
 
888
994
  function dumpUAVariableType(xw: XmlWriter, node: UAVariableType) {
995
+ assert(node.nodeClass === NodeClass.VariableType);
889
996
  xw.visitedNode = xw.visitedNode || {};
890
997
  assert(!xw.visitedNode[_hash(node)]);
891
998
  xw.visitedNode[_hash(node)] = 1;
@@ -942,6 +1049,7 @@ function dumpUAObject(xw: XmlWriter, node: UAObject) {
942
1049
  xw.writeComment("Object - " + b(xw, node.browseName) + " }}}} ");
943
1050
  }
944
1051
  function _dumpUAObject(xw: XmlWriter, node: UAObject) {
1052
+ assert(node.nodeClass === NodeClass.Object);
945
1053
  xw.visitedNode = xw.visitedNode || {};
946
1054
  assert(!xw.visitedNode[_hash(node)]);
947
1055
  xw.visitedNode[_hash(node)] = 1;
@@ -994,6 +1102,7 @@ function dumpAggregates(xw: XmlWriter, node: BaseNode) {
994
1102
  }
995
1103
 
996
1104
  function dumpUAObjectType(xw: XmlWriter, node: UAObjectTypeImpl) {
1105
+ assert(node.nodeClass === NodeClass.ObjectType);
997
1106
  assert(node instanceof UAObjectTypeImpl);
998
1107
  xw.writeComment("ObjectType - " + b(xw, node.browseName) + " {{{{ ");
999
1108
  _markAsVisited(xw, node);
@@ -1012,6 +1121,7 @@ function dumpUAObjectType(xw: XmlWriter, node: UAObjectTypeImpl) {
1012
1121
  }
1013
1122
 
1014
1123
  function dumpUAMethod(xw: XmlWriter, node: UAMethod) {
1124
+ assert(node.nodeClass === NodeClass.Method);
1015
1125
  _markAsVisited(xw, node);
1016
1126
 
1017
1127
  dumpReferencedNodes(xw, node, false);
@@ -1043,18 +1153,17 @@ function resolveDataTypeName(addressSpace: IAddressSpace, dataType: string | Nod
1043
1153
  return dataTypeNode.browseName;
1044
1154
  }
1045
1155
 
1046
- function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
1156
+ function buildUpAliases(node: BaseNode, xw: XmlWriter, data: BuildAliasesData) {
1047
1157
  const addressSpace = node.addressSpace;
1048
1158
 
1049
- options.aliases = options.aliases || {};
1050
- options.aliases_visited = options.aliases_visited || {};
1159
+ if (!data.aliases_visited) data.aliases_visited = {};
1051
1160
 
1052
1161
  const k = _hash(node);
1053
1162
  // istanbul ignore next
1054
- if (options.aliases_visited[k]) {
1163
+ if (data.aliases_visited[k]) {
1055
1164
  return;
1056
1165
  }
1057
- options.aliases_visited[k] = 1;
1166
+ data.aliases_visited[k] = 1;
1058
1167
 
1059
1168
  // put datatype into aliases list
1060
1169
  if (node.nodeClass === NodeClass.Variable || node.nodeClass === NodeClass.VariableType) {
@@ -1064,8 +1173,8 @@ function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
1064
1173
  // name
1065
1174
  const dataTypeName = b(xw, resolveDataTypeName(addressSpace, nodeV.dataType));
1066
1175
  if (dataTypeName) {
1067
- if (!options.aliases[dataTypeName]) {
1068
- options.aliases[dataTypeName] = n(xw, nodeV.dataType);
1176
+ if (!data.aliases[dataTypeName]) {
1177
+ data.aliases[dataTypeName] = n(xw, nodeV.dataType);
1069
1178
  }
1070
1179
  }
1071
1180
  }
@@ -1074,8 +1183,8 @@ function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
1074
1183
  // name
1075
1184
  const dataTypeName = b(xw, resolveDataTypeName(addressSpace, nodeV.dataType));
1076
1185
  if (dataTypeName) {
1077
- if (!options.aliases[dataTypeName]) {
1078
- options.aliases[dataTypeName] = n(xw, nodeV.dataType);
1186
+ if (!data.aliases[dataTypeName]) {
1187
+ data.aliases[dataTypeName] = n(xw, nodeV.dataType);
1079
1188
  }
1080
1189
  }
1081
1190
  }
@@ -1084,11 +1193,11 @@ function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
1084
1193
  function collectReferenceNameInAlias(reference: UAReference) {
1085
1194
  // reference.referenceType
1086
1195
  const key = b(xw, getReferenceType(reference).browseName);
1087
- if (!options.aliases.key) {
1196
+ if (!data.aliases.key) {
1088
1197
  if (reference.referenceType.namespace === 0) {
1089
- options.aliases[key] = reference.referenceType.toString().replace("ns=0;", "");
1198
+ data.aliases[key] = reference.referenceType.toString().replace("ns=0;", "");
1090
1199
  } else {
1091
- options.aliases[key] = n(xw, reference.referenceType);
1200
+ data.aliases[key] = n(xw, reference.referenceType);
1092
1201
  }
1093
1202
  }
1094
1203
  }
@@ -1096,7 +1205,7 @@ function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
1096
1205
  node.allReferences().forEach(collectReferenceNameInAlias);
1097
1206
  }
1098
1207
 
1099
- function writeAliases(xw: XmlWriter, aliases: any) {
1208
+ function writeAliases(xw: XmlWriter, aliases: Record<string, NodeIdString>) {
1100
1209
  xw.startElement("Aliases");
1101
1210
 
1102
1211
  if (aliases) {
@@ -1154,11 +1263,29 @@ function sortByNodeId(a: { nodeId: NodeId }, b: { nodeId: NodeId }) {
1154
1263
  return a.nodeId.toString() < b.nodeId.toString() ? -1 : 1;
1155
1264
  }
1156
1265
 
1157
- export function dumpXml(node: BaseNode, options: any): void {
1266
+ interface Dumpable {
1267
+ dumpXML(xw: typeof XMLWriter): void;
1268
+ }
1269
+ type NodeIdString = string;
1270
+
1271
+ export interface BuildAliasesData {
1272
+ aliases: Record<string, NodeIdString>;
1273
+ aliases_visited?: Record<string, unknown>;
1274
+ }
1275
+ interface DumpData extends BuildAliasesData {
1276
+ elements: Dumpable[];
1277
+ index_el: Record<string, number>;
1278
+ }
1279
+
1280
+ export interface DumpXMLOptions {
1281
+ /** */
1282
+ }
1283
+
1284
+ export function dumpXml(node: BaseNode, options: DumpXMLOptions): void {
1158
1285
  const namespace = node.namespace as NamespacePrivate;
1159
1286
 
1160
1287
  // make a first visit so that we determine which node to output and in which order
1161
- const nodesToVisit: any = {};
1288
+ const data: DumpData = { aliases: {}, aliases_visited: {}, index_el: {}, elements: [] };
1162
1289
 
1163
1290
  const dependency = constructNamespaceDependency(namespace);
1164
1291
  const translationTable = constructNamespaceTranslationTable(dependency);
@@ -1166,7 +1293,7 @@ export function dumpXml(node: BaseNode, options: any): void {
1166
1293
  const xw = new XMLWriter(true);
1167
1294
  xw.translationTable = translationTable;
1168
1295
 
1169
- visitUANode(node, nodesToVisit, false);
1296
+ visitUANode(node, data, false);
1170
1297
 
1171
1298
  xw.startDocument({ encoding: "utf-8" });
1172
1299
  xw.startElement("UANodeSet");
@@ -1176,10 +1303,26 @@ export function dumpXml(node: BaseNode, options: any): void {
1176
1303
  xw.writeAttribute("LastModified", new Date().toISOString());
1177
1304
  xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd");
1178
1305
 
1179
- buildUpAliases(node, xw, nodesToVisit);
1180
- writeAliases(xw, nodesToVisit.aliases);
1306
+ buildUpAliases(node, xw, data);
1307
+ writeAliases(xw, data.aliases);
1308
+
1309
+ const xmlNamspace = {
1310
+ default: { namespace: "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd" }
1311
+ };
1181
1312
 
1182
- for (const el of nodesToVisit.elements) {
1313
+ xw.startElement("Extensions");
1314
+ {
1315
+ xw.startElement("Extension");
1316
+ {
1317
+ xw.startElement("ModelInfo");
1318
+ xw.writeAttribute("NodeOPCUA");
1319
+ xw.endElement();
1320
+ }
1321
+ xw.endElement();
1322
+ }
1323
+ xw.endElement();
1324
+
1325
+ for (const el of data.elements!) {
1183
1326
  el.dumpXML(xw);
1184
1327
  }
1185
1328
 
@@ -1211,11 +1354,20 @@ UADataTypeImpl.prototype.dumpXML = function (xw: XmlWriter) {
1211
1354
  dumpUADataType(xw, this);
1212
1355
  };
1213
1356
 
1357
+ function makeTypeXsd(namespaceUri: string): string {
1358
+ return namespaceUri.replace(/\/$/, "") + "/Type.xsd";
1359
+ }
1360
+
1214
1361
  // eslint-disable-next-line max-statements
1215
1362
  NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1216
1363
  const dependency = constructNamespaceDependency(this);
1217
1364
  const translationTable = constructNamespaceTranslationTable(dependency);
1218
1365
 
1366
+ const namespaceArrayNode = this.addressSpace.findNode(VariableIds.Server_NamespaceArray);
1367
+ const namespaceArray: string[] = namespaceArrayNode
1368
+ ? namespaceArrayNode.readAttribute(null, AttributeIds.Value).value.value
1369
+ : [];
1370
+
1219
1371
  const xw = new XMLWriter(true);
1220
1372
  xw.translationTable = translationTable;
1221
1373
 
@@ -1225,12 +1377,31 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1225
1377
  xw.writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
1226
1378
  xw.writeAttribute("xmlns:uax", "http://opcfoundation.org/UA/2008/02/Types.xsd");
1227
1379
  xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd");
1380
+
1381
+ const namespacesMap: Record<string, string> = {
1382
+ "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd": "",
1383
+ "http://opcfoundation.org/UA/2008/02/Types.xsd": "uax",
1384
+ "http://www.w3.org/2001/XMLSchema-instance": "xsi"
1385
+ };
1386
+
1387
+ for (const namespace of dependency) {
1388
+ if (namespace.index === 0) {
1389
+ continue;
1390
+ }
1391
+ const translatedIndex = translationTable[namespace.index];
1392
+
1393
+ const smallName = `ns${translatedIndex}`;
1394
+ xw.writeAttribute(`xmlns:${smallName}`, makeTypeXsd(namespace.namespaceUri));
1395
+ namespacesMap[namespace.namespaceUri] = smallName;
1396
+ }
1228
1397
  // xx xw.writeAttribute("Version", "1.02");
1229
1398
  // xx xw.writeAttribute("LastModified", (new Date()).toISOString());
1230
1399
 
1231
1400
  // ------------- INamespace Uris
1232
1401
  xw.startElement("NamespaceUris");
1233
1402
 
1403
+ initXmlWriterEx(xw, namespacesMap, namespaceArray);
1404
+
1234
1405
  // xx const namespaceArray = namespace.addressSpace.getNamespaceArray();
1235
1406
  for (const depend of dependency) {
1236
1407
  if (depend.index === 0) {
@@ -1264,11 +1435,11 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1264
1435
  }
1265
1436
  xw.endElement();
1266
1437
 
1267
- const s: any = {};
1438
+ const data: BuildAliasesData = { aliases: {} };
1268
1439
  for (const node of this.nodeIterator()) {
1269
- buildUpAliases(node, xw, s);
1440
+ buildUpAliases(node, xw, data);
1270
1441
  }
1271
- writeAliases(xw, s.aliases);
1442
+ writeAliases(xw, data.aliases);
1272
1443
 
1273
1444
  xw.visitedNode = {};
1274
1445
 
@@ -1281,10 +1452,8 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1281
1452
 
1282
1453
  // -------------- Dictionaries
1283
1454
  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)
1455
+
1456
+ const getDataTypeDescription = (opcBinaryTypeSystem: UAObject) => {
1288
1457
  const nodeToBrowse = new BrowseDescription({
1289
1458
  browseDirection: BrowseDirection.Forward,
1290
1459
  includeSubtypes: false,
@@ -1295,12 +1464,9 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1295
1464
  });
1296
1465
  const result = opcBinaryTypeSystem.browseNode(nodeToBrowse).filter((r) => r.nodeId.namespace === this.index);
1297
1466
  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
- }
1467
+ return result;
1468
+ };
1469
+
1304
1470
  // -------------- DataTypes
1305
1471
  const dataTypes = [...this._dataTypeIterator()].sort(sortByBrowseName);
1306
1472
  if (dataTypes.length) {
@@ -1311,7 +1477,42 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1311
1477
  dumpNodeInXml(xw, dataType);
1312
1478
  }
1313
1479
  }
1480
+
1481
+ // --------------
1482
+ const opcBinaryTypeSystem = addressSpace.findNode(ObjectIds.OPCBinarySchema_TypeSystem) as UAObject;
1483
+ const opcXmlSchemaTypeSystem = addressSpace.findNode(ObjectIds.XmlSchema_TypeSystem) as UAObject;
1484
+
1485
+ if (opcBinaryTypeSystem) {
1486
+ // let find all DataType dictionary node corresponding to a given namespace
1487
+ // (have DataTypeDictionaryType)
1488
+ const result = getDataTypeDescription(opcBinaryTypeSystem);
1489
+ if (result.length === 1) {
1490
+ xw.writeComment("DataSystem - Binary");
1491
+ const dataSystemType = addressSpace.findNode(result[0].nodeId)! as UAVariable;
1492
+ const types = dataSystemType.getComponents();
1493
+ for (const f of types) {
1494
+ dumpNodeInXml(xw, f);
1495
+ }
1496
+ dumpNodeInXml(xw, dataSystemType);
1497
+ }
1498
+ }
1499
+
1500
+ if (opcXmlSchemaTypeSystem) {
1501
+ const result = getDataTypeDescription(opcXmlSchemaTypeSystem);
1502
+ if (result.length === 1) {
1503
+ xw.writeComment("DataSystem - Xml");
1504
+ const dataSystemType = addressSpace.findNode(result[0].nodeId)! as UAVariable;
1505
+
1506
+ const types = dataSystemType.getComponents();
1507
+ for (const f of types) {
1508
+ dumpNodeInXml(xw, f);
1509
+ }
1510
+
1511
+ dumpNodeInXml(xw, dataSystemType);
1512
+ }
1513
+ }
1314
1514
  }
1515
+
1315
1516
  // -------------- ObjectTypes
1316
1517
  xw.writeComment("ObjectTypes");
1317
1518
  const objectTypes = [...this._objectTypeIterator()].sort(sortByBrowseName);