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.
- package/dist/source/loader/ensure_datatype_extracted.js +1 -1
- package/dist/source/loader/ensure_datatype_extracted.js.map +1 -1
- package/dist/source/loader/load_nodeset2.js +9 -22
- package/dist/source/loader/load_nodeset2.js.map +1 -1
- package/dist/source/xml_writer.d.ts +5 -1
- package/dist/src/address_space.js +1 -1
- package/dist/src/address_space.js.map +1 -1
- package/dist/src/apply_condition_refresh.d.ts +1 -1
- package/dist/src/apply_condition_refresh.js +5 -5
- package/dist/src/apply_condition_refresh.js.map +1 -1
- package/dist/src/base_node_impl.d.ts +1 -0
- package/dist/src/base_node_impl.js +83 -54
- package/dist/src/base_node_impl.js.map +1 -1
- package/dist/src/base_node_private.d.ts +23 -3
- package/dist/src/base_node_private.js +3 -2
- package/dist/src/base_node_private.js.map +1 -1
- package/dist/src/index_current.d.ts +1 -1
- package/dist/src/index_current.js +2 -3
- package/dist/src/index_current.js.map +1 -1
- package/dist/src/namespace_impl.d.ts +4 -1
- package/dist/src/namespace_impl.js +10 -2
- package/dist/src/namespace_impl.js.map +1 -1
- package/dist/src/namespace_private.d.ts +2 -1
- package/dist/src/namespace_private.js.map +1 -1
- package/dist/src/nodeset_tools/construct_namespace_dependency.d.ts +3 -1
- package/dist/src/nodeset_tools/construct_namespace_dependency.js +35 -5
- package/dist/src/nodeset_tools/construct_namespace_dependency.js.map +1 -1
- package/dist/src/nodeset_tools/nodeset_to_xml.d.ts +4 -2
- package/dist/src/nodeset_tools/nodeset_to_xml.js +44 -59
- package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
- package/dist/src/ua_data_type_impl.d.ts +2 -0
- package/dist/src/ua_data_type_impl.js +10 -15
- package/dist/src/ua_data_type_impl.js.map +1 -1
- package/dist/src/ua_reference_type_impl.d.ts +1 -1
- package/dist/src/ua_reference_type_impl.js +1 -1
- package/dist/src/ua_reference_type_impl.js.map +1 -1
- package/dist/src/ua_variable_impl.d.ts +2 -0
- package/dist/src/ua_variable_impl.js +49 -11
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/package.json +40 -40
- package/source/loader/ensure_datatype_extracted.ts +1 -1
- package/source/loader/load_nodeset2.ts +22 -36
- package/source/xml_writer.ts +5 -1
- package/src/address_space.ts +1 -2
- package/src/apply_condition_refresh.ts +5 -5
- package/src/base_node_impl.ts +86 -59
- package/src/base_node_private.ts +26 -10
- package/src/index_current.ts +1 -1
- package/src/namespace_impl.ts +13 -3
- package/src/namespace_private.ts +7 -1
- package/src/nodeset_tools/construct_namespace_dependency.ts +42 -5
- package/src/nodeset_tools/nodeset_to_xml.ts +57 -84
- package/src/ua_data_type_impl.ts +12 -15
- package/src/ua_reference_type_impl.ts +2 -2
- package/src/ua_variable_impl.ts +74 -31
- package/test_helpers/test_fixtures/dataType_with_union.xml +90 -1
- 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:
|
|
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 (!
|
|
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(
|
|
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
|
-
|
|
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 &&
|
|
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 &&
|
|
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) {
|
package/source/xml_writer.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
export interface ITranslationTable {
|
|
2
|
+
[key: number]: number;
|
|
3
|
+
}
|
|
1
4
|
export interface XmlWriter {
|
|
2
|
-
translationTable:
|
|
5
|
+
translationTable: ITranslationTable;
|
|
6
|
+
priorityTable: number[];
|
|
3
7
|
visitedNode: any;
|
|
4
8
|
|
|
5
9
|
startDocument(options: { encoding: string; version: string }): void;
|
package/src/address_space.ts
CHANGED
|
@@ -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,
|
|
7
|
+
export function apply_condition_refresh(this: BaseNodeImpl, cache?: ConditionRefreshCache): void {
|
|
8
8
|
// visit all notifiers recursively
|
|
9
|
-
|
|
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 (!
|
|
24
|
-
|
|
23
|
+
if (!cache[key]) {
|
|
24
|
+
cache[key] = notifier;
|
|
25
25
|
if (notifier._conditionRefresh) {
|
|
26
|
-
notifier._conditionRefresh(
|
|
26
|
+
notifier._conditionRefresh(cache);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
}
|
package/src/base_node_impl.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
572
|
-
|
|
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
|
/**
|
package/src/base_node_private.ts
CHANGED
|
@@ -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:
|
|
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):
|
|
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 &&
|
|
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
|
}
|
package/src/index_current.ts
CHANGED
|
@@ -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
|
|
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";
|
package/src/namespace_impl.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
package/src/namespace_private.ts
CHANGED
|
@@ -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;
|