node-opcua-address-space 2.81.0 → 2.83.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 (57) hide show
  1. package/dist/source/loader/ensure_datatype_extracted.js +1 -1
  2. package/dist/source/loader/ensure_datatype_extracted.js.map +1 -1
  3. package/dist/source/loader/load_nodeset2.js +9 -22
  4. package/dist/source/loader/load_nodeset2.js.map +1 -1
  5. package/dist/source/xml_writer.d.ts +5 -1
  6. package/dist/src/address_space.js +1 -1
  7. package/dist/src/address_space.js.map +1 -1
  8. package/dist/src/apply_condition_refresh.d.ts +1 -1
  9. package/dist/src/apply_condition_refresh.js +5 -5
  10. package/dist/src/apply_condition_refresh.js.map +1 -1
  11. package/dist/src/base_node_impl.d.ts +1 -0
  12. package/dist/src/base_node_impl.js +83 -54
  13. package/dist/src/base_node_impl.js.map +1 -1
  14. package/dist/src/base_node_private.d.ts +23 -3
  15. package/dist/src/base_node_private.js +3 -2
  16. package/dist/src/base_node_private.js.map +1 -1
  17. package/dist/src/index_current.d.ts +1 -1
  18. package/dist/src/index_current.js +2 -3
  19. package/dist/src/index_current.js.map +1 -1
  20. package/dist/src/namespace_impl.d.ts +4 -1
  21. package/dist/src/namespace_impl.js +10 -2
  22. package/dist/src/namespace_impl.js.map +1 -1
  23. package/dist/src/namespace_private.d.ts +2 -1
  24. package/dist/src/namespace_private.js.map +1 -1
  25. package/dist/src/nodeset_tools/construct_namespace_dependency.d.ts +3 -1
  26. package/dist/src/nodeset_tools/construct_namespace_dependency.js +35 -5
  27. package/dist/src/nodeset_tools/construct_namespace_dependency.js.map +1 -1
  28. package/dist/src/nodeset_tools/nodeset_to_xml.d.ts +4 -2
  29. package/dist/src/nodeset_tools/nodeset_to_xml.js +44 -59
  30. package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
  31. package/dist/src/ua_data_type_impl.d.ts +2 -0
  32. package/dist/src/ua_data_type_impl.js +10 -15
  33. package/dist/src/ua_data_type_impl.js.map +1 -1
  34. package/dist/src/ua_reference_type_impl.d.ts +1 -1
  35. package/dist/src/ua_reference_type_impl.js +1 -1
  36. package/dist/src/ua_reference_type_impl.js.map +1 -1
  37. package/dist/src/ua_variable_impl.d.ts +2 -0
  38. package/dist/src/ua_variable_impl.js +49 -11
  39. package/dist/src/ua_variable_impl.js.map +1 -1
  40. package/package.json +40 -40
  41. package/source/loader/ensure_datatype_extracted.ts +1 -1
  42. package/source/loader/load_nodeset2.ts +22 -36
  43. package/source/xml_writer.ts +5 -1
  44. package/src/address_space.ts +1 -2
  45. package/src/apply_condition_refresh.ts +5 -5
  46. package/src/base_node_impl.ts +86 -59
  47. package/src/base_node_private.ts +26 -10
  48. package/src/index_current.ts +1 -1
  49. package/src/namespace_impl.ts +13 -3
  50. package/src/namespace_private.ts +7 -1
  51. package/src/nodeset_tools/construct_namespace_dependency.ts +42 -5
  52. package/src/nodeset_tools/nodeset_to_xml.ts +57 -84
  53. package/src/ua_data_type_impl.ts +12 -15
  54. package/src/ua_reference_type_impl.ts +2 -2
  55. package/src/ua_variable_impl.ts +74 -31
  56. package/test_helpers/test_fixtures/dataType_with_union.xml +90 -1
  57. package/test_helpers/test_fixtures/datatype_as_per_1.04.xml +38 -10
@@ -12,6 +12,7 @@ import {
12
12
  CreateNodeOptions,
13
13
  IAddressSpace,
14
14
  INamespace,
15
+ RequiredModel,
15
16
  UADataType,
16
17
  UAVariable,
17
18
  UAVariableType
@@ -52,11 +53,11 @@ import * as semver from "semver";
52
53
 
53
54
  import { AddressSpacePrivate } from "../../src/address_space_private";
54
55
  import { NamespacePrivate } from "../../src/namespace_private";
56
+ import { NodeSetLoaderOptions } from "../interfaces/nodeset_loader_options";
55
57
  import { promoteObjectsAndVariables } from "./namespace_post_step";
56
58
  import { ensureDatatypeExtracted } from "./ensure_datatype_extracted";
57
59
  import { decodeXmlExtensionObject } from "./decode_xml_extension_object";
58
60
  import { makeSemverCompatible } from "./make_semver_compatible";
59
- import { NodeSetLoaderOptions } from "../interfaces/nodeset_loader_options";
60
61
 
61
62
  const doDebug = checkDebugFlag(__filename);
62
63
  const debugLog = make_debugLog(__filename);
@@ -150,9 +151,9 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
150
151
  const addressSpace1 = addressSpace as AddressSpacePrivate;
151
152
  addressSpace1.suspendBackReference = true;
152
153
 
153
- options.loadDeprecatedNodes = options.loadDeprecatedNodes === undefined ? true: options.loadDeprecatedNodes;
154
+ options.loadDeprecatedNodes = options.loadDeprecatedNodes === undefined ? true : options.loadDeprecatedNodes;
154
155
  options.loadDraftNodes = options.loadDraftNodes || false;
155
-
156
+
156
157
  const postTasks: Task[] = [];
157
158
  const postTasks0_InitializeVariable: Task[] = [];
158
159
  const postTasks0_DecodePojoString: Task[] = [];
@@ -225,6 +226,8 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
225
226
  return;
226
227
  }
227
228
  const namespace = addressSpace1.getNamespace(namespaceUri);
229
+
230
+ // istanbul ignore next
228
231
  if (!namespace) {
229
232
  throw new Error(
230
233
  "cannot find namespace for " +
@@ -254,6 +257,8 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
254
257
  // check that required models exist already in the address space
255
258
  for (const requiredModel of model.requiredModels) {
256
259
  const existingNamespace = addressSpace1.getNamespace(requiredModel.modelUri);
260
+
261
+ // istanbul ignore next
257
262
  if (!existingNamespace) {
258
263
  errorLog(
259
264
  "Please ensure that the required namespace ",
@@ -274,6 +279,7 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
274
279
  const requiredSemver = makeSemverCompatible(requiredVersion);
275
280
  return semver.lt(existingSemver, requiredSemver);
276
281
  };
282
+
277
283
  if (isLowerVersion(existingNamespace.version, requiredModel.version)) {
278
284
  errorLog(
279
285
  "Expecting ",
@@ -302,6 +308,7 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
302
308
  const existingNamespace = addressSpace1.getNamespace(model.modelUri);
303
309
  if (existingNamespace) {
304
310
  // special treatment for namespace 0
311
+ // istanbul ignore else
305
312
  if (model.modelUri === "http://opcfoundation.org/UA/") {
306
313
  namespace = existingNamespace;
307
314
  } else {
@@ -309,6 +316,7 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
309
316
  }
310
317
  } else {
311
318
  namespace = addressSpace1.registerNamespace(model.modelUri);
319
+ namespace.setRequiredModels(model.requiredModels)
312
320
  }
313
321
 
314
322
  namespace.version = model.version;
@@ -516,25 +524,6 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
516
524
  if (canIngore({ isDraft: this.isDraft, isDeprecated: this.isDeprecated }, this.obj)) {
517
525
  return;
518
526
  }
519
- /*
520
- export interface StructureFieldOptions {
521
- name?: UAString ; // **
522
- description?: (LocalizedTextLike | null); // **
523
- dataType?: (NodeIdLike | null);
524
- valueRank?: Int32 ;
525
- arrayDimensions?: UInt32 [] | null;
526
- maxStringLength?: UInt32 ;
527
- isOptional?: UABoolean ;
528
- }
529
- export interface EnumValueTypeOptions {
530
- value?: Int64 ;
531
- displayName?: (LocalizedTextLike | null);
532
- description?: (LocalizedTextLike | null); // **
533
- }
534
- export interface EnumFieldOptions extends EnumValueTypeOptions {
535
- name?: UAString ; // **
536
- }
537
- */
538
527
 
539
528
  const definitionFields = this.definitionFields as StructureFieldOptions[] | EnumFieldOptions[];
540
529
 
@@ -872,11 +861,14 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
872
861
  break;
873
862
  default: {
874
863
  // istanbul ignore next
875
- if (! this._cloneFragment) {
864
+ if (!this._cloneFragment) {
876
865
  // the XML file is probably not exposing standard UA extension object correctly.
877
866
  // this has been seen in some generated xml files using the dataType nodeId instead of the default encoding
878
- // nodeid
879
- errorLog("[NODE-OPCUA-E12] standard OPCUA Extension object from (namespace=0) has a invalid TypeId", self.typeDefinitionId.toString());
867
+ // nodeid
868
+ errorLog(
869
+ "[NODE-OPCUA-E12] standard OPCUA Extension object from (namespace=0) has a invalid TypeId",
870
+ self.typeDefinitionId.toString()
871
+ );
880
872
  break;
881
873
  }
882
874
  this.bodyXML = this._cloneFragment!.value;
@@ -1416,8 +1408,6 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
1416
1408
  // do them later
1417
1409
  postTasks1_InitializeVariable.push(task);
1418
1410
  }
1419
-
1420
-
1421
1411
  } else {
1422
1412
  const task = async (addressSpace2: IAddressSpace) => {
1423
1413
  const dataTypeNode = capturedVariable.dataType;
@@ -1543,11 +1533,7 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
1543
1533
  }
1544
1534
  };
1545
1535
 
1546
- interface RequiredModel {
1547
- modelUri: string;
1548
- version: string;
1549
- publicationDate: Date;
1550
- }
1536
+
1551
1537
  interface Model {
1552
1538
  modelUri: string;
1553
1539
  version: string;
@@ -1726,7 +1712,8 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
1726
1712
  doDebug && debugLog(chalk.bgGreenBright("Performing post loading tasks -------------------------------------------"));
1727
1713
  await performPostLoadingTasks(postTasks);
1728
1714
 
1729
- doDebug && debugLog(chalk.bgGreenBright("Performing post loading task: Initializing Simple Variables ---------------------"));
1715
+ doDebug &&
1716
+ debugLog(chalk.bgGreenBright("Performing post loading task: Initializing Simple Variables ---------------------"));
1730
1717
  await performPostLoadingTasks(postTasks0_InitializeVariable);
1731
1718
 
1732
1719
  doDebug && debugLog(chalk.bgGreenBright("Performing DataType extraction -------------------------------------------"));
@@ -1748,7 +1735,8 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
1748
1735
  doDebug && debugLog(chalk.bgGreenBright("Performing post loading task: Decoding Pojo String (parsing XML objects) -"));
1749
1736
  await performPostLoadingTasks(postTasks0_DecodePojoString);
1750
1737
 
1751
- doDebug && debugLog(chalk.bgGreenBright("Performing post loading task: Initializing Complex Variables ---------------------"));
1738
+ doDebug &&
1739
+ debugLog(chalk.bgGreenBright("Performing post loading task: Initializing Complex Variables ---------------------"));
1752
1740
  await performPostLoadingTasks(postTasks1_InitializeVariable);
1753
1741
 
1754
1742
  doDebug && debugLog(chalk.bgGreenBright("Performing post loading tasks: (assigning Extension Object to Variables) -"));
@@ -1775,8 +1763,6 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
1775
1763
  };
1776
1764
  }
1777
1765
 
1778
-
1779
-
1780
1766
  export class NodeSetLoader {
1781
1767
  _s: NodeSet2ParserEngine;
1782
1768
  constructor(addressSpace: IAddressSpace, private options?: NodeSetLoaderOptions) {
@@ -1,5 +1,9 @@
1
+ export interface ITranslationTable {
2
+ [key: number]: number;
3
+ }
1
4
  export interface XmlWriter {
2
- translationTable: any;
5
+ translationTable: ITranslationTable;
6
+ priorityTable: number[];
3
7
  visitedNode: any;
4
8
 
5
9
  startDocument(options: { encoding: string; version: string }): void;
@@ -1451,8 +1451,7 @@ export class AddressSpace implements AddressSpacePrivate {
1451
1451
  if (!baseType) {
1452
1452
  return topMostBaseTypeNode;
1453
1453
  }
1454
-
1455
- assert(typeof baseType === "string" || baseType instanceof BaseNodeImpl);
1454
+ assert(typeof baseType === "string" || baseType instanceof BaseNodeImpl || baseType instanceof NodeId);
1456
1455
  let baseTypeNode: T;
1457
1456
  if (baseType instanceof BaseNodeImpl) {
1458
1457
  baseTypeNode = baseType as BaseNode as T;
@@ -4,9 +4,9 @@ import { BaseNodeImpl } from "./base_node_impl";
4
4
  import { UAObjectImpl } from "./ua_object_impl";
5
5
 
6
6
  export type ConditionRefreshCache = { [key in string]: UAObject };
7
- export function apply_condition_refresh(this: BaseNodeImpl, _cache?: ConditionRefreshCache): void {
7
+ export function apply_condition_refresh(this: BaseNodeImpl, cache?: ConditionRefreshCache): void {
8
8
  // visit all notifiers recursively
9
- _cache = _cache || {};
9
+ cache = cache || {};
10
10
  const notifiers = this.getNotifiers();
11
11
  const eventSources = this.getEventSources();
12
12
 
@@ -20,10 +20,10 @@ export function apply_condition_refresh(this: BaseNodeImpl, _cache?: ConditionRe
20
20
 
21
21
  for (const notifier of arr) {
22
22
  const key = notifier.nodeId.toString();
23
- if (!_cache[key]) {
24
- _cache[key] = notifier;
23
+ if (!cache[key]) {
24
+ cache[key] = notifier;
25
25
  if (notifier._conditionRefresh) {
26
- notifier._conditionRefresh(_cache);
26
+ notifier._conditionRefresh(cache);
27
27
  }
28
28
  }
29
29
  }
@@ -54,6 +54,7 @@ import { lowerFirstLetter } from "node-opcua-utils";
54
54
  import { DataType, VariantArrayType } from "node-opcua-variant";
55
55
 
56
56
  import { UAStateVariable } from "node-opcua-nodeset-ua";
57
+ import { ObjectTypeIds, VariableTypeIds } from "node-opcua-constants";
57
58
 
58
59
  import { XmlWriter } from "../source/xml_writer";
59
60
  import { dumpReferenceDescriptions, dumpReferences } from "../source/helpers/dump_tools";
@@ -209,7 +210,19 @@ export class BaseNodeImpl extends EventEmitter implements BaseNode {
209
210
  const _cache = BaseNode_getCache(this);
210
211
  if (!_cache.typeDefinition) {
211
212
  const has_type_definition_ref = this.findReference("HasTypeDefinition", true);
212
- _cache.typeDefinition = has_type_definition_ref ? has_type_definition_ref.nodeId : null;
213
+ let nodeId = has_type_definition_ref ? has_type_definition_ref.nodeId : null;
214
+ if (!nodeId) {
215
+ switch (this.nodeClass) {
216
+ case NodeClass.Object:
217
+ nodeId = coerceNodeId(ObjectTypeIds.BaseObjectType);
218
+ break;
219
+ case NodeClass.Variable:
220
+ nodeId = coerceNodeId(VariableTypeIds.BaseVariableType);
221
+ break;
222
+ default:
223
+ }
224
+ }
225
+ _cache.typeDefinition = nodeId as NodeId;
213
226
  }
214
227
  return _cache.typeDefinition;
215
228
  }
@@ -221,9 +234,12 @@ export class BaseNodeImpl extends EventEmitter implements BaseNode {
221
234
  const _cache = BaseNode_getCache(this);
222
235
  if (undefined === _cache.typeDefinitionObj) {
223
236
  const nodeId = this.typeDefinition;
224
- _cache.typeDefinitionObj = nodeId ? this.addressSpace.findNode(nodeId) : null;
237
+ _cache.typeDefinitionObj = nodeId ? (this.addressSpace.findNode(nodeId) as UAObjectType | UAVariableType) : null;
225
238
  }
226
- return _cache.typeDefinitionObj;
239
+ if (!_cache.typeDefinitionObj) {
240
+ warningLog("cannot find typeDefinitionObj ", this.browseName.toString(), this.nodeId.toString());
241
+ }
242
+ return _cache.typeDefinitionObj as UAObjectType | UAVariableType;
227
243
  }
228
244
 
229
245
  public get parentNodeId(): NodeId | undefined {
@@ -374,26 +390,9 @@ export class BaseNodeImpl extends EventEmitter implements BaseNode {
374
390
  return results;
375
391
  }
376
392
 
377
- public findReferences(referenceType: string | NodeId | UAReferenceType, isForward = true): UAReference[] {
378
- const _cache = BaseNode_getCache(this);
379
- const _private = BaseNode_getPrivate(this);
380
-
381
- const referenceTypeNode = this._coerceReferenceType(referenceType);
382
- if (!referenceTypeNode) {
383
- // note: when loading nodeset2.xml files, reference type may not exit yet
384
- // throw new Error("expecting valid reference name " + strReference);
385
- return [];
386
- }
387
- const hash = "_ref_" + referenceTypeNode.nodeId.toString() + isForward.toString();
388
- if (_cache[hash]) {
389
- return _cache[hash];
390
- }
391
-
392
- // istanbul ignore next
393
- if (doDebug && !this.addressSpace.findReferenceType(referenceTypeNode.nodeId)) {
394
- throw new Error("expecting valid reference name " + referenceType);
395
- }
396
393
 
394
+ public findReferences_no_cache(referenceTypeNode: UAReferenceType, isForward = true): UAReference[] {
395
+ const _private = BaseNode_getPrivate(this);
397
396
  const result: UAReference[] = [];
398
397
  for (const ref of Object.values(_private._referenceIdx)) {
399
398
  if (ref.isForward === isForward) {
@@ -410,8 +409,28 @@ export class BaseNodeImpl extends EventEmitter implements BaseNode {
410
409
  }
411
410
  }
412
411
  }
412
+ return result;
413
+ }
413
414
 
414
- _cache[hash] = result;
415
+ public findReferences(referenceType: string | NodeId | UAReferenceType, isForward = true): UAReference[] {
416
+ const _cache = BaseNode_getCache(this);
417
+ const referenceTypeNode = this._coerceReferenceType(referenceType);
418
+ if (!referenceTypeNode) {
419
+ // note: when loading nodeset2.xml files, reference type may not exit yet
420
+ // throw new Error("expecting valid reference name " + strReference);
421
+ return [];
422
+ }
423
+ _cache._ref = _cache._ref || {};
424
+ const hash = "_ref_" + referenceTypeNode.nodeId.toString() + isForward.toString();
425
+ if (_cache._ref[hash]) {
426
+ return _cache._ref[hash];
427
+ }
428
+ // istanbul ignore next
429
+ if (doDebug && !this.addressSpace.findReferenceType(referenceTypeNode.nodeId)) {
430
+ throw new Error("expecting valid reference name " + referenceType);
431
+ }
432
+ const result = this.findReferences_no_cache(referenceTypeNode, isForward);
433
+ _cache._ref[hash] = result;
415
434
  return result;
416
435
  }
417
436
 
@@ -440,66 +459,72 @@ export class BaseNodeImpl extends EventEmitter implements BaseNode {
440
459
  * return an array with the Aggregates of this object.
441
460
  */
442
461
  public getAggregates(): BaseNode[] {
443
- const _cache = BaseNode_getCache(this);
444
- if (!_cache._aggregates) {
445
- _cache._aggregates = this.findReferencesExAsObject("Aggregates", BrowseDirection.Forward);
446
- }
447
- return _cache._aggregates;
462
+ // const _cache = BaseNode_getCache(this);
463
+ // if (!_cache._aggregates) {
464
+ // _cache._aggregates = this.findReferencesExAsObject("Aggregates", BrowseDirection.Forward);
465
+ // }
466
+ // return _cache._aggregates;
467
+ return this.findReferencesExAsObject("Aggregates", BrowseDirection.Forward);
448
468
  }
449
469
 
450
470
  /**
451
471
  * return an array with the components of this object.
452
472
  */
453
473
  public getComponents(): BaseNode[] {
454
- const _cache = BaseNode_getCache(this);
455
- if (!_cache._components) {
456
- _cache._components = this.findReferencesExAsObject("HasComponent", BrowseDirection.Forward);
457
- }
458
- return _cache._components;
474
+ // const _cache = BaseNode_getCache(this);
475
+ // if (!_cache._components) {
476
+ // _cache._components = this.findReferencesExAsObject("HasComponent", BrowseDirection.Forward);
477
+ // }
478
+ // return _cache._components;
479
+ return this.findReferencesExAsObject("HasComponent", BrowseDirection.Forward);
459
480
  }
460
481
 
461
482
  /**
462
483
  * return a array with the properties of this object.
463
484
  */
464
485
  public getProperties(): BaseNode[] {
465
- const _cache = BaseNode_getCache(this);
466
- if (!_cache._properties) {
467
- _cache._properties = this.findReferencesExAsObject("HasProperty", BrowseDirection.Forward);
468
- }
469
- return _cache._properties;
486
+ // const _cache = BaseNode_getCache(this);
487
+ // if (!_cache._properties) {
488
+ // _cache._properties = this.findReferencesExAsObject("HasProperty", BrowseDirection.Forward);
489
+ // }
490
+ // return _cache._properties;
491
+ return this.findReferencesExAsObject("HasProperty", BrowseDirection.Forward);
470
492
  }
471
493
 
472
494
  /**
473
495
  * return a array with the notifiers of this object.
474
496
  */
475
497
  public getNotifiers(): BaseNode[] {
476
- const _cache = BaseNode_getCache(this);
477
- if (!_cache._notifiers) {
478
- _cache._notifiers = this.findReferencesAsObject("HasNotifier", true);
479
- }
480
- return _cache._notifiers;
498
+ // const _cache = BaseNode_getCache(this);
499
+ // if (!_cache._notifiers) {
500
+ // _cache._notifiers = this.findReferencesAsObject("HasNotifier", true);
501
+ // }
502
+ // return _cache._notifiers;
503
+ return this.findReferencesAsObject("HasNotifier", true);
481
504
  }
482
505
 
483
506
  /**
484
507
  * return a array with the event source of this object.
485
508
  */
486
509
  public getEventSources(): BaseNode[] {
487
- const _cache = BaseNode_getCache(this);
488
- if (!_cache._eventSources) {
489
- _cache._eventSources = this.findReferencesAsObject("HasEventSource", true);
490
- }
491
- return _cache._eventSources;
510
+ // const _cache = BaseNode_getCache(this);
511
+ // if (!_cache._eventSources) {
512
+ // _cache._eventSources = this.findReferencesAsObject("HasEventSource", true);
513
+ // }
514
+ // return _cache._eventSources;
515
+ return this.findReferencesAsObject("HasEventSource", true);
492
516
  }
493
517
 
494
518
  /**
495
519
  * return a array of the objects for which this node is an EventSource
496
520
  */
497
521
  public getEventSourceOfs(): BaseNode[] {
498
- const _cache = BaseNode_getCache(this);
499
- if (!_cache._eventSources) {
500
- _cache._eventSources = this.findReferencesAsObject("HasEventSource", false);
501
- }
502
- return _cache._eventSources;
522
+ // const _cache = BaseNode_getCache(this);
523
+ // if (!_cache._eventSources) {
524
+ // _cache._eventSources = this.findReferencesAsObject("HasEventSource", false);
525
+ // }
526
+ // return _cache._eventSources;
527
+ return this.findReferencesAsObject("HasEventSource", false);
503
528
  }
504
529
 
505
530
  /**
@@ -566,12 +591,14 @@ export class BaseNodeImpl extends EventEmitter implements BaseNode {
566
591
  * Note: internally, methods are special types of components
567
592
  */
568
593
  public getMethods(): UAMethod[] {
569
- const _cache = BaseNode_getCache(this);
570
- if (!_cache._methods) {
571
- const components = this.getComponents();
572
- _cache._methods = components.filter((obj) => obj.nodeClass === NodeClass.Method);
573
- }
574
- return _cache._methods;
594
+ // const _cache = BaseNode_getCache(this);
595
+ // if (!_cache._methods) {
596
+ // const components = this.getComponents();
597
+ // _cache._methods = components.filter((obj) => obj.nodeClass === NodeClass.Method) as UAMethod[];
598
+ // }
599
+ // return _cache._methods;
600
+ const components = this.getComponents();
601
+ return components.filter((obj) => obj.nodeClass === NodeClass.Method) as UAMethod[];
575
602
  }
576
603
 
577
604
  /**
@@ -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
  }
@@ -37,7 +37,7 @@ export * from "./extension_object_array_node";
37
37
  export * from "./event_data";
38
38
 
39
39
  export { NamespaceOptions } from "./nodeid_manager";
40
- export { dumpXml } from "./nodeset_tools/nodeset_to_xml";
40
+ export * from "./nodeset_tools/nodeset_to_xml";
41
41
  export { dumpToBSD } from "./nodeset_tools/dump_to_bsd";
42
42
  export { adjustNamespaceArray } from "./nodeset_tools/adjust_namespace_array";
43
43
  export { makeAttributeEventName } from "./base_node_impl";
@@ -46,6 +46,7 @@ import {
46
46
  CreateNodeOptions,
47
47
  EnumerationItem,
48
48
  INamespace,
49
+ RequiredModel,
49
50
  UADataType,
50
51
  UAEventType,
51
52
  UAMethod,
@@ -123,6 +124,7 @@ import { UAReferenceTypeImpl } from "./ua_reference_type_impl";
123
124
  import { UAViewImpl } from "./ua_view_impl";
124
125
  import { UAStateMachineImpl, UATransitionImpl } from "./state_machine/finite_state_machine";
125
126
  import { _addMultiStateValueDiscrete } from "./data_access/ua_multistate_value_discrete_impl";
127
+ import { notDeepEqual } from "assert";
126
128
 
127
129
  function _makeHashKey(nodeId: NodeId): string | number {
128
130
  switch (nodeId.identifierType) {
@@ -218,7 +220,6 @@ export class NamespaceImpl implements NamespacePrivate {
218
220
  public readonly namespaceUri: string;
219
221
  public addressSpace: AddressSpacePrivate;
220
222
  public readonly index: number;
221
-
222
223
  public emulateVersion103 = false;
223
224
 
224
225
  public version = "0.0.0";
@@ -226,6 +227,7 @@ export class NamespaceImpl implements NamespacePrivate {
226
227
 
227
228
  public registerSymbolicNames = false;
228
229
 
230
+ private _requiredModels?: RequiredModel[];
229
231
  private _objectTypeMap: Map<string, UAObjectType>;
230
232
  private _variableTypeMap: Map<string, UAVariableType>;
231
233
  private _referenceTypeMap: Map<string, UAReferenceType>;
@@ -1416,7 +1418,13 @@ export class NamespaceImpl implements NamespacePrivate {
1416
1418
  // State and Transition
1417
1419
  // -------------------------------------------------------------------------
1418
1420
  public toNodeset2XML(): string {
1419
- return "";
1421
+ return "<toNodeset2XML>has not be installed</toNodeset2XML>!";
1422
+ }
1423
+ public setRequiredModels(requiredModels: RequiredModel[]): void {
1424
+ this._requiredModels = requiredModels;
1425
+ }
1426
+ public getRequiredModels(): RequiredModel[] | undefined {
1427
+ return this._requiredModels;
1420
1428
  }
1421
1429
 
1422
1430
  // -------------------------------------------------------------------------
@@ -1896,7 +1904,9 @@ export class NamespaceImpl implements NamespacePrivate {
1896
1904
  private _registerObjectType(node: UAObjectType) {
1897
1905
  assert(this.index === node.nodeId.namespace);
1898
1906
  const key = node.browseName.name!;
1899
- assert(!this._objectTypeMap.has(key), " UAObjectType already declared");
1907
+ if (this._objectTypeMap.has(key)) {
1908
+ throw new Error(" UAObjectType already declared " + node.browseName.toString() + " " + node.nodeId.toString());
1909
+ }
1900
1910
  this._objectTypeMap.set(key, node);
1901
1911
  }
1902
1912
 
@@ -10,14 +10,18 @@ import {
10
10
  CreateNodeOptions,
11
11
  ModellingRuleType,
12
12
  INamespace,
13
- UADataType
13
+ UADataType,
14
+ RequiredModel
14
15
  } from "node-opcua-address-space-base";
15
16
 
16
17
  import { AddressSpacePrivate } from "./address_space_private";
17
18
 
19
+
18
20
  export interface NamespacePrivate extends INamespace {
19
21
  addressSpace: AddressSpacePrivate;
20
22
 
23
+ setRequiredModels(requiredModels: RequiredModel[]): void;
24
+
21
25
  nodeIterator(): IterableIterator<BaseNode>;
22
26
 
23
27
  constructNodeId(options: ConstructNodeIdOptions): NodeId;
@@ -35,6 +39,8 @@ export interface NamespacePrivate extends INamespace {
35
39
  _dataTypeIterator(): IterableIterator<UADataType>;
36
40
 
37
41
  registerSymbolicNames: boolean;
42
+
43
+
38
44
  }
39
45
 
40
46
  export declare const NamespacePrivate: new (options: any) => NamespacePrivate;