node-opcua-address-space 2.167.0 → 2.169.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/namespace_post_step.js +25 -17
- package/dist/source/loader/namespace_post_step.js.map +1 -1
- package/dist/source/session_context.d.ts +3 -1
- package/dist/source/session_context.js +26 -1
- package/dist/source/session_context.js.map +1 -1
- package/dist/src/address_space.d.ts +14 -11
- package/dist/src/address_space.js +55 -54
- package/dist/src/address_space.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.d.ts +8 -8
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js +19 -19
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.d.ts +11 -13
- package/dist/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.js +21 -13
- package/dist/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_condition_impl.js +1 -1
- package/dist/src/alarms_and_conditions/ua_condition_impl.js.map +1 -1
- package/dist/src/base_node_impl.d.ts +1 -0
- package/dist/src/base_node_impl.js +26 -15
- package/dist/src/base_node_impl.js.map +1 -1
- package/dist/src/namespace_impl.d.ts +40 -31
- package/dist/src/namespace_impl.js +174 -161
- package/dist/src/namespace_impl.js.map +1 -1
- package/dist/src/namespace_private.d.ts +12 -4
- package/dist/src/namespace_private.js +1 -4
- package/dist/src/namespace_private.js.map +1 -1
- package/dist/src/ua_method_impl.d.ts +11 -9
- package/dist/src/ua_method_impl.js +24 -27
- package/dist/src/ua_method_impl.js.map +1 -1
- package/dist/tsconfig_base.tsbuildinfo +1 -1
- package/package.json +35 -37
- package/source/loader/namespace_post_step.ts +28 -19
- package/source/session_context.ts +30 -1
- package/src/address_space.ts +113 -109
- package/src/alarms_and_conditions/ua_alarm_condition_impl.ts +26 -28
- package/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.ts +33 -27
- package/src/alarms_and_conditions/ua_condition_impl.ts +1 -1
- package/src/base_node_impl.ts +27 -14
- package/src/namespace_impl.ts +232 -201
- package/src/namespace_private.ts +15 -9
- package/src/ua_method_impl.ts +43 -50
package/src/namespace_impl.ts
CHANGED
|
@@ -3,33 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
// tslint:disable:no-console
|
|
5
5
|
import chalk from "chalk";
|
|
6
|
-
|
|
7
|
-
import { assert } from "node-opcua-assert";
|
|
8
|
-
import { coerceInt64 } from "node-opcua-basic-types";
|
|
9
|
-
import { AxisScaleEnumeration } from "node-opcua-data-access";
|
|
10
|
-
import { AccessRestrictionsFlag, coerceLocalizedText, coerceQualifiedName, QualifiedNameLike } from "node-opcua-data-model";
|
|
11
|
-
import { QualifiedName } from "node-opcua-data-model";
|
|
12
|
-
import { BrowseDirection } from "node-opcua-data-model";
|
|
13
|
-
import { NodeClass } from "node-opcua-data-model";
|
|
14
|
-
import { dumpIf, make_errorLog, make_warningLog } from "node-opcua-debug";
|
|
15
|
-
import { NodeIdLike, NodeIdType, resolveNodeId } from "node-opcua-nodeid";
|
|
16
|
-
import { NodeId } from "node-opcua-nodeid";
|
|
17
|
-
import { StatusCodes } from "node-opcua-status-code";
|
|
18
|
-
import {
|
|
19
|
-
Argument,
|
|
20
|
-
ArgumentOptions,
|
|
21
|
-
AxisInformation,
|
|
22
|
-
EnumDefinition,
|
|
23
|
-
EnumField,
|
|
24
|
-
EnumValueType,
|
|
25
|
-
EUInformation,
|
|
26
|
-
Range,
|
|
27
|
-
RolePermissionType,
|
|
28
|
-
RolePermissionTypeOptions
|
|
29
|
-
} from "node-opcua-types";
|
|
30
|
-
import { isNullOrUndefined } from "node-opcua-utils";
|
|
31
|
-
import { DataType, Variant, VariantArrayType, VariantOptions, verifyRankAndDimensions } from "node-opcua-variant";
|
|
32
|
-
import {
|
|
6
|
+
import type {
|
|
33
7
|
AddBaseNodeOptions,
|
|
34
8
|
AddEnumerationTypeOptions,
|
|
35
9
|
AddMethodOptions,
|
|
@@ -57,40 +31,69 @@ import {
|
|
|
57
31
|
UAVariableType,
|
|
58
32
|
UAView
|
|
59
33
|
} from "node-opcua-address-space-base";
|
|
60
|
-
import {
|
|
61
|
-
|
|
34
|
+
import { assert } from "node-opcua-assert";
|
|
35
|
+
import { coerceInt64 } from "node-opcua-basic-types";
|
|
36
|
+
import { AxisScaleEnumeration } from "node-opcua-data-access";
|
|
62
37
|
import {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
38
|
+
AccessRestrictionsFlag,
|
|
39
|
+
BrowseDirection,
|
|
40
|
+
coerceLocalizedText,
|
|
41
|
+
coerceQualifiedName,
|
|
42
|
+
NodeClass,
|
|
43
|
+
QualifiedName,
|
|
44
|
+
type QualifiedNameLike
|
|
45
|
+
} from "node-opcua-data-model";
|
|
46
|
+
import { dumpIf, make_errorLog, make_warningLog } from "node-opcua-debug";
|
|
47
|
+
import { coerceNodeId, NodeId, type NodeIdLike, NodeIdType, resolveNodeId } from "node-opcua-nodeid";
|
|
48
|
+
import type { UAAnalogItem, UADataItem, UAInitialState, UAState } from "node-opcua-nodeset-ua";
|
|
49
|
+
import { StatusCodes } from "node-opcua-status-code";
|
|
70
50
|
import {
|
|
51
|
+
Argument,
|
|
52
|
+
type ArgumentOptions,
|
|
53
|
+
AxisInformation,
|
|
54
|
+
EnumDefinition,
|
|
55
|
+
EnumField,
|
|
56
|
+
EnumValueType,
|
|
57
|
+
EUInformation,
|
|
58
|
+
Range,
|
|
59
|
+
type RolePermissionType,
|
|
60
|
+
type RolePermissionTypeOptions
|
|
61
|
+
} from "node-opcua-types";
|
|
62
|
+
import { isNullOrUndefined } from "node-opcua-utils";
|
|
63
|
+
import { DataType, Variant, VariantArrayType, type VariantOptions, verifyRankAndDimensions } from "node-opcua-variant";
|
|
64
|
+
import type {
|
|
71
65
|
InstantiateAlarmConditionOptions,
|
|
72
66
|
InstantiateLimitAlarmOptions,
|
|
73
67
|
InstantiateOffNormalAlarmOptions,
|
|
74
68
|
UATwoStateDiscreteEx,
|
|
75
69
|
UAYArrayItemEx
|
|
76
70
|
} from "../source";
|
|
77
|
-
import {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
import {
|
|
84
|
-
import {
|
|
85
|
-
import {
|
|
86
|
-
import {
|
|
87
|
-
import { UAConditionEx } from "../source/interfaces/alarms_and_conditions/ua_condition_ex";
|
|
88
|
-
import {
|
|
89
|
-
import {
|
|
90
|
-
import {
|
|
71
|
+
import type {
|
|
72
|
+
AddMultiStateDiscreteOptions,
|
|
73
|
+
AddMultiStateValueDiscreteOptions,
|
|
74
|
+
AddTwoStateDiscreteOptions,
|
|
75
|
+
AddTwoStateVariableOptions
|
|
76
|
+
} from "../source/address_space_ts";
|
|
77
|
+
import type { InstantiateExclusiveDeviationAlarmOptions } from "../source/interfaces/alarms_and_conditions/instantiate_exclusive_deviation_alarm_options";
|
|
78
|
+
import type { InstantiateNonExclusiveDeviationAlarmOptions } from "../source/interfaces/alarms_and_conditions/instantiate_non_exclusive_deviation_alarm_options";
|
|
79
|
+
import type { InstantiateNonExclusiveLimitAlarmOptions } from "../source/interfaces/alarms_and_conditions/instantiate_non_exclusive_limit_alarm_options";
|
|
80
|
+
import type { UAAlarmConditionEx } from "../source/interfaces/alarms_and_conditions/ua_alarm_condition_ex";
|
|
81
|
+
import type { UAConditionEx } from "../source/interfaces/alarms_and_conditions/ua_condition_ex";
|
|
82
|
+
import type { UADiscreteAlarmEx } from "../source/interfaces/alarms_and_conditions/ua_discrete_alarm_ex";
|
|
83
|
+
import type { UAExclusiveDeviationAlarmEx } from "../source/interfaces/alarms_and_conditions/ua_exclusive_deviation_alarm_ex";
|
|
84
|
+
import type { UAExclusiveLimitAlarmEx } from "../source/interfaces/alarms_and_conditions/ua_exclusive_limit_alarm_ex";
|
|
85
|
+
import type { UALimitAlarmEx } from "../source/interfaces/alarms_and_conditions/ua_limit_alarm_ex";
|
|
86
|
+
import type { UANonExclusiveDeviationAlarmEx } from "../source/interfaces/alarms_and_conditions/ua_non_exclusive_deviation_alarm_ex";
|
|
87
|
+
import type { UANonExclusiveLimitAlarmEx } from "../source/interfaces/alarms_and_conditions/ua_non_exclusive_limit_alarm_ex";
|
|
88
|
+
import type { UAMultiStateValueDiscreteEx } from "../source/interfaces/data_access/ua_multistate_value_discrete_ex";
|
|
89
|
+
import type { UAStateMachineEx } from "../source/interfaces/state_machine/ua_state_machine_type";
|
|
90
|
+
import type { UATransitionEx } from "../source/interfaces/state_machine/ua_transition_ex";
|
|
91
|
+
import type { AddAnalogDataItemOptions, AddDataItemOptions } from "../source/namespace_data_access";
|
|
92
|
+
import type { UATwoStateVariableEx } from "../source/ua_two_state_variable_ex";
|
|
91
93
|
|
|
92
94
|
import { _handle_delete_node_model_change_event, _handle_model_change_event } from "./address_space_change_event_tools";
|
|
93
|
-
import { AddressSpacePrivate } from "./address_space_private";
|
|
95
|
+
import type { AddressSpacePrivate } from "./address_space_private";
|
|
96
|
+
import { UAAcknowledgeableConditionImpl, UAAlarmConditionImpl } from "./alarms_and_conditions";
|
|
94
97
|
import { UAConditionImpl } from "./alarms_and_conditions/ua_condition_impl";
|
|
95
98
|
import { UADiscreteAlarmImpl } from "./alarms_and_conditions/ua_discrete_alarm_impl";
|
|
96
99
|
import { UAExclusiveDeviationAlarmImpl } from "./alarms_and_conditions/ua_exclusive_deviation_alarm_impl";
|
|
@@ -98,30 +101,28 @@ import { UAExclusiveLimitAlarmImpl } from "./alarms_and_conditions/ua_exclusive_
|
|
|
98
101
|
import { UALimitAlarmImpl } from "./alarms_and_conditions/ua_limit_alarm_impl";
|
|
99
102
|
import { UANonExclusiveDeviationAlarmImpl } from "./alarms_and_conditions/ua_non_exclusive_deviation_alarm_impl";
|
|
100
103
|
import { UANonExclusiveLimitAlarmImpl } from "./alarms_and_conditions/ua_non_exclusive_limit_alarm_impl";
|
|
101
|
-
import {
|
|
102
|
-
import {
|
|
104
|
+
import { type UAOffNormalAlarmEx, UAOffNormalAlarmImpl } from "./alarms_and_conditions/ua_off_normal_alarm_impl";
|
|
105
|
+
import { BaseNodeImpl } from "./base_node_impl";
|
|
103
106
|
import { add_dataItem_stuff } from "./data_access/add_dataItem_stuff";
|
|
104
|
-
import {
|
|
105
|
-
|
|
106
|
-
import {
|
|
107
|
-
|
|
107
|
+
import { _addMultiStateDiscrete, type UAMultiStateDiscreteImpl } from "./data_access/ua_multistate_discrete_impl";
|
|
108
|
+
import { _addMultiStateValueDiscrete } from "./data_access/ua_multistate_value_discrete_impl";
|
|
109
|
+
import { _addTwoStateDiscrete } from "./data_access/ua_two_state_discrete_impl";
|
|
108
110
|
//
|
|
109
|
-
import { NamespacePrivate, UANamespace_process_modelling_rule } from "./namespace_private";
|
|
110
|
-
import { BaseNodeImpl } from "./base_node_impl";
|
|
111
|
-
import { UAVariableImpl } from "./ua_variable_impl";
|
|
111
|
+
import { type NamespacePrivate, UANamespace_process_modelling_rule } from "./namespace_private";
|
|
112
112
|
|
|
113
|
-
import { ConstructNodeIdOptions, NodeIdManager } from "./nodeid_manager";
|
|
114
|
-
import { _addTwoStateDiscrete } from "./data_access/ua_two_state_discrete_impl";
|
|
113
|
+
import { type ConstructNodeIdOptions, NodeIdManager } from "./nodeid_manager";
|
|
115
114
|
import { coerceRolePermissions } from "./role_permissions";
|
|
116
|
-
import {
|
|
115
|
+
import type { UAStateMachineImpl, UATransitionImpl } from "./state_machine/finite_state_machine";
|
|
116
|
+
// state machine
|
|
117
|
+
import { _addTwoStateVariable } from "./state_machine/ua_two_state_variable";
|
|
117
118
|
import { UADataTypeImpl } from "./ua_data_type_impl";
|
|
118
|
-
import { UAObjectTypeImpl } from "./ua_object_type_impl";
|
|
119
119
|
import { UAMethodImpl } from "./ua_method_impl";
|
|
120
|
-
import {
|
|
120
|
+
import { UAObjectImpl } from "./ua_object_impl";
|
|
121
|
+
import { UAObjectTypeImpl } from "./ua_object_type_impl";
|
|
121
122
|
import { UAReferenceTypeImpl } from "./ua_reference_type_impl";
|
|
123
|
+
import { UAVariableImpl } from "./ua_variable_impl";
|
|
124
|
+
import { UAVariableTypeImpl } from "./ua_variable_type_impl";
|
|
122
125
|
import { UAViewImpl } from "./ua_view_impl";
|
|
123
|
-
import { UAStateMachineImpl, UATransitionImpl } from "./state_machine/finite_state_machine";
|
|
124
|
-
import { _addMultiStateValueDiscrete } from "./data_access/ua_multistate_value_discrete_impl";
|
|
125
126
|
|
|
126
127
|
function _makeHashKey(nodeId: NodeId): string | number {
|
|
127
128
|
switch (nodeId.identifierType) {
|
|
@@ -158,7 +159,7 @@ function detachNode(node: BaseNode) {
|
|
|
158
159
|
const nonHierarchicalReferences = node.findReferencesEx("NonHierarchicalReferences", BrowseDirection.Inverse);
|
|
159
160
|
for (const ref of nonHierarchicalReferences) {
|
|
160
161
|
assert(!ref.isForward);
|
|
161
|
-
ref.node
|
|
162
|
+
ref.node?.removeReference({
|
|
162
163
|
isForward: !ref.isForward,
|
|
163
164
|
nodeId: node.nodeId,
|
|
164
165
|
referenceType: ref.referenceType
|
|
@@ -172,7 +173,7 @@ function detachNode(node: BaseNode) {
|
|
|
172
173
|
continue;
|
|
173
174
|
}
|
|
174
175
|
assert(ref.isForward);
|
|
175
|
-
ref.node
|
|
176
|
+
ref.node?.removeReference({
|
|
176
177
|
isForward: !ref.isForward,
|
|
177
178
|
nodeId: node.nodeId,
|
|
178
179
|
referenceType: ref.referenceType
|
|
@@ -183,7 +184,7 @@ function detachNode(node: BaseNode) {
|
|
|
183
184
|
const hierarchicalReferences = node.findReferencesEx("HierarchicalReferences", BrowseDirection.Inverse);
|
|
184
185
|
for (const ref of hierarchicalReferences) {
|
|
185
186
|
assert(!ref.isForward);
|
|
186
|
-
const parent = addressSpace.findNode(ref.nodeId)
|
|
187
|
+
const parent = addressSpace.findNode(ref.nodeId) as BaseNode;
|
|
187
188
|
parent.removeReference({
|
|
188
189
|
isForward: !ref.isForward,
|
|
189
190
|
nodeId: node.nodeId,
|
|
@@ -200,6 +201,23 @@ interface NamespaceConstructorOptions {
|
|
|
200
201
|
publicationDate: Date;
|
|
201
202
|
version: string;
|
|
202
203
|
}
|
|
204
|
+
|
|
205
|
+
function toNodeId(nodeId: NodeId | { nodeId: NodeId } | string | number | undefined): NodeId | undefined {
|
|
206
|
+
if (!nodeId) {
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
if (nodeId instanceof NodeId) {
|
|
210
|
+
return nodeId;
|
|
211
|
+
}
|
|
212
|
+
if (typeof nodeId === "string") {
|
|
213
|
+
return coerceNodeId(nodeId);
|
|
214
|
+
}
|
|
215
|
+
if (typeof nodeId === "number") {
|
|
216
|
+
return coerceNodeId(nodeId);
|
|
217
|
+
}
|
|
218
|
+
return nodeId.nodeId;
|
|
219
|
+
}
|
|
220
|
+
|
|
203
221
|
/**
|
|
204
222
|
*
|
|
205
223
|
* @constructor
|
|
@@ -232,7 +250,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
232
250
|
private _dataTypeMap: Map<string, UADataType>;
|
|
233
251
|
private _referenceTypeMapInv: Map<string, UAReferenceType>;
|
|
234
252
|
private _nodeIdManager: NodeIdManager;
|
|
235
|
-
private _nodeid_index: Map<string | number| Buffer, BaseNode>;
|
|
253
|
+
private _nodeid_index: Map<string | number | Buffer, BaseNode>;
|
|
236
254
|
private _aliases: Map<string, NodeId>;
|
|
237
255
|
private defaultAccessRestrictions?: AccessRestrictionsFlag;
|
|
238
256
|
private defaultRolePermissions?: RolePermissionType[];
|
|
@@ -240,7 +258,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
240
258
|
constructor(options: NamespaceConstructorOptions) {
|
|
241
259
|
// c8 ignore next
|
|
242
260
|
if (!(typeof options.namespaceUri === "string")) {
|
|
243
|
-
throw new Error(
|
|
261
|
+
throw new Error(`NamespaceImpl constructor: namespaceUri must exists and be a string : got ${options.namespaceUri}`);
|
|
244
262
|
}
|
|
245
263
|
// c8 ignore next
|
|
246
264
|
if (typeof options.index !== "number") {
|
|
@@ -269,6 +287,22 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
269
287
|
return this.index === 0 ? this : this.addressSpace.getDefaultNamespace();
|
|
270
288
|
}
|
|
271
289
|
|
|
290
|
+
public toJSON(): Record<string, string | number | undefined> {
|
|
291
|
+
return {
|
|
292
|
+
index: this.index,
|
|
293
|
+
namespaceUri: this.namespaceUri,
|
|
294
|
+
version: this.version
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
public toString(): string {
|
|
299
|
+
return `Namespace({ index: ${this.index}, namespaceUri: "${this.namespaceUri}" })`;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
public [Symbol.for("nodejs.util.inspect.custom")](): string {
|
|
303
|
+
return this.toString();
|
|
304
|
+
}
|
|
305
|
+
|
|
272
306
|
public dispose(): void {
|
|
273
307
|
for (const node of this.nodeIterator()) {
|
|
274
308
|
(<BaseNodeImpl>node).dispose();
|
|
@@ -334,7 +368,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
334
368
|
public findNode(nodeId: string | NodeId): BaseNode | null {
|
|
335
369
|
if (typeof nodeId === "string") {
|
|
336
370
|
if (nodeId.match(regExp1)) {
|
|
337
|
-
nodeId =
|
|
371
|
+
nodeId = `ns=${this.index};${nodeId}`;
|
|
338
372
|
}
|
|
339
373
|
}
|
|
340
374
|
nodeId = resolveNodeId(nodeId);
|
|
@@ -421,12 +455,9 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
421
455
|
*
|
|
422
456
|
*/
|
|
423
457
|
public addObjectType(options: AddObjectTypeOptions): UAObjectType {
|
|
424
|
-
assert(!Object.
|
|
425
|
-
assert(!Object.
|
|
426
|
-
assert(
|
|
427
|
-
!Object.prototype.hasOwnProperty.call(options, "arrayDimensions"),
|
|
428
|
-
"an objectType should not have a arrayDimensions"
|
|
429
|
-
);
|
|
458
|
+
assert(!Object.hasOwn(options, "dataType"), "an objectType should not have a dataType");
|
|
459
|
+
assert(!Object.hasOwn(options, "valueRank"), "an objectType should not have a valueRank");
|
|
460
|
+
assert(!Object.hasOwn(options, "arrayDimensions"), "an objectType should not have a arrayDimensions");
|
|
430
461
|
return this._addObjectOrVariableType(options, "BaseObjectType", NodeClass.ObjectType) as UAObjectType;
|
|
431
462
|
}
|
|
432
463
|
|
|
@@ -446,7 +477,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
446
477
|
*
|
|
447
478
|
*/
|
|
448
479
|
public addVariableType(options: AddVariableTypeOptions): UAVariableType {
|
|
449
|
-
assert(!Object.
|
|
480
|
+
assert(!Object.hasOwn(options, "arrayDimension"), "Do you mean ArrayDimensions ?");
|
|
450
481
|
|
|
451
482
|
// dataType
|
|
452
483
|
options.dataType = options.dataType || "Int32";
|
|
@@ -460,7 +491,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
460
491
|
|
|
461
492
|
variableType.dataType = options.dataType;
|
|
462
493
|
variableType.valueRank = options.valueRank || 0;
|
|
463
|
-
variableType.arrayDimensions = options.arrayDimensions
|
|
494
|
+
variableType.arrayDimensions = options.arrayDimensions || [];
|
|
464
495
|
|
|
465
496
|
return variableType as UAVariableType;
|
|
466
497
|
}
|
|
@@ -470,7 +501,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
470
501
|
*/
|
|
471
502
|
public addVariable(options: AddVariableOptions): UAVariable {
|
|
472
503
|
assert(arguments.length === 1, "Invalid arguments IAddressSpace#addVariable now takes only one argument.");
|
|
473
|
-
if (Object.
|
|
504
|
+
if (Object.hasOwn(options, "propertyOf") && options.propertyOf) {
|
|
474
505
|
assert(!options.typeDefinition || options.typeDefinition === "PropertyType");
|
|
475
506
|
options.typeDefinition = options.typeDefinition || "PropertyType";
|
|
476
507
|
} else {
|
|
@@ -480,23 +511,21 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
480
511
|
}
|
|
481
512
|
|
|
482
513
|
public addView(options: AddViewOptions): UAView {
|
|
483
|
-
assert(
|
|
484
|
-
assert(options);
|
|
485
|
-
assert(Object.prototype.hasOwnProperty.call(options, "browseName"));
|
|
486
|
-
assert(Object.prototype.hasOwnProperty.call(options, "organizedBy"));
|
|
514
|
+
assert(Object.hasOwn(options, "browseName"));
|
|
515
|
+
assert(Object.hasOwn(options, "organizedBy"));
|
|
487
516
|
const browseName = options.browseName;
|
|
488
517
|
assert(typeof browseName === "string");
|
|
489
518
|
|
|
490
519
|
const addressSpace = this.addressSpace;
|
|
491
|
-
const baseDataVariableTypeId = addressSpace.findVariableType("BaseDataVariableType")
|
|
520
|
+
const baseDataVariableTypeId = addressSpace.findVariableType("BaseDataVariableType")?.nodeId;
|
|
492
521
|
|
|
493
522
|
// ------------------------------------------ TypeDefinition
|
|
494
|
-
const
|
|
523
|
+
const _typeDefinition = options.typeDefinition || baseDataVariableTypeId;
|
|
495
524
|
options.references = options.references || [];
|
|
496
525
|
|
|
497
526
|
options.references.push({
|
|
498
527
|
isForward: true,
|
|
499
|
-
nodeId:
|
|
528
|
+
nodeId: toNodeId(_typeDefinition) || NodeId.nullNodeId,
|
|
500
529
|
referenceType: "HasTypeDefinition"
|
|
501
530
|
});
|
|
502
531
|
|
|
@@ -504,7 +533,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
504
533
|
assert(!createOptions.nodeClass);
|
|
505
534
|
createOptions.nodeClass = NodeClass.View;
|
|
506
535
|
|
|
507
|
-
const view = this.createNode(createOptions)
|
|
536
|
+
const view = this.createNode(createOptions) as UAView;
|
|
508
537
|
assert(view.nodeId instanceof NodeId);
|
|
509
538
|
assert(view.nodeClass === NodeClass.View);
|
|
510
539
|
return view;
|
|
@@ -537,7 +566,6 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
537
566
|
* @return {BaseNode}
|
|
538
567
|
*/
|
|
539
568
|
public addFolder(parentFolder: UAObject, options: AddFolderOptions | string): UAObject {
|
|
540
|
-
|
|
541
569
|
if (typeof options === "string") {
|
|
542
570
|
options = { browseName: options };
|
|
543
571
|
}
|
|
@@ -546,7 +574,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
546
574
|
|
|
547
575
|
assert(!(options as any).typeDefinition, "addFolder does not expect typeDefinition to be defined ");
|
|
548
576
|
const typeDefinition = addressSpace._coerceTypeDefinition("FolderType");
|
|
549
|
-
parentFolder = addressSpace._coerceFolder(parentFolder)
|
|
577
|
+
parentFolder = addressSpace._coerceFolder(parentFolder) as UAObject;
|
|
550
578
|
(options as any).nodeClass = NodeClass.Object;
|
|
551
579
|
(options as any).references = [
|
|
552
580
|
{ referenceType: "HasTypeDefinition", isForward: true, nodeId: typeDefinition },
|
|
@@ -569,7 +597,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
569
597
|
const options1 = options as CreateNodeOptions;
|
|
570
598
|
options1.nodeClass = NodeClass.ReferenceType;
|
|
571
599
|
options1.references = options.references || [];
|
|
572
|
-
options1.nodeId = options.nodeId
|
|
600
|
+
options1.nodeId = options.nodeId;
|
|
573
601
|
|
|
574
602
|
if (options.subtypeOf) {
|
|
575
603
|
const subtypeOfNodeId = addressSpace._coerceType(options.subtypeOf, "References", NodeClass.ReferenceType);
|
|
@@ -599,9 +627,9 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
599
627
|
|
|
600
628
|
*/
|
|
601
629
|
public createDataType(options: CreateDataTypeOptions): UADataType {
|
|
602
|
-
assert(Object.
|
|
603
|
-
assert(!Object.
|
|
604
|
-
assert(Object.
|
|
630
|
+
assert(Object.hasOwn(options, "isAbstract"), "must provide isAbstract");
|
|
631
|
+
assert(!Object.hasOwn(options, "nodeClass"));
|
|
632
|
+
assert(Object.hasOwn(options, "browseName"), "must provide a browseName");
|
|
605
633
|
|
|
606
634
|
const options1 = options as unknown as { nodeClass: NodeClass; references: AddReferenceOpts[]; subtypeOf: UADataType };
|
|
607
635
|
options1.nodeClass = NodeClass.DataType;
|
|
@@ -648,7 +676,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
648
676
|
assert(isNonEmptyQualifiedName(options.browseName));
|
|
649
677
|
// xx assert(Object.prototype.hasOwnProperty.call(options,"browseName") && options.browseName.length > 0);
|
|
650
678
|
|
|
651
|
-
assert(Object.
|
|
679
|
+
assert(Object.hasOwn(options, "nodeClass"));
|
|
652
680
|
options.references = addressSpace.normalizeReferenceTypes(options.references);
|
|
653
681
|
|
|
654
682
|
const references = _copy_references(options.references);
|
|
@@ -691,7 +719,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
691
719
|
node = this.findNode(nodeId);
|
|
692
720
|
// c8 ignore next
|
|
693
721
|
if (!node) {
|
|
694
|
-
throw new Error(
|
|
722
|
+
throw new Error(` deleteNode : cannot find node with nodeId${nodeId.toString()}`);
|
|
695
723
|
}
|
|
696
724
|
} else if (nodeOrNodeId instanceof BaseNodeImpl) {
|
|
697
725
|
node = nodeOrNodeId;
|
|
@@ -713,13 +741,13 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
713
741
|
const hierarchicalReferences = node.findReferencesEx("HierarchicalReferences", BrowseDirection.Inverse);
|
|
714
742
|
for (const ref of hierarchicalReferences) {
|
|
715
743
|
assert(!ref.isForward);
|
|
716
|
-
const parent = addressSpace.findNode(ref.nodeId)
|
|
744
|
+
const parent = addressSpace.findNode(ref.nodeId) as BaseNodeImpl;
|
|
717
745
|
assert(parent);
|
|
718
746
|
parent._on_child_removed(node);
|
|
719
747
|
}
|
|
720
748
|
|
|
721
749
|
function deleteNodePointedByReference(ref: { nodeId: NodeId }) {
|
|
722
|
-
const o = addressSpace.findNode(ref.nodeId)
|
|
750
|
+
const o = addressSpace.findNode(ref.nodeId) as BaseNode;
|
|
723
751
|
addressSpace.deleteNode(o.nodeId);
|
|
724
752
|
}
|
|
725
753
|
|
|
@@ -760,10 +788,10 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
760
788
|
};
|
|
761
789
|
|
|
762
790
|
for (const referenceType of this._referenceTypeMap.values()) {
|
|
763
|
-
standardNodeIds.referenceTypeIds[referenceType
|
|
791
|
+
standardNodeIds.referenceTypeIds[referenceType?.browseName?.name as string] = referenceType.nodeId.toString();
|
|
764
792
|
}
|
|
765
793
|
for (const objectType of this._objectTypeMap.values()) {
|
|
766
|
-
standardNodeIds.objectTypeIds[objectType
|
|
794
|
+
standardNodeIds.objectTypeIds[objectType?.browseName?.name as string] = objectType.nodeId.toString();
|
|
767
795
|
}
|
|
768
796
|
return standardNodeIds;
|
|
769
797
|
}
|
|
@@ -795,13 +823,13 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
795
823
|
options.subtypeOf = options.subtypeOf || "BaseEventType";
|
|
796
824
|
// are eventType always abstract ?? No => Condition can be instantiated!
|
|
797
825
|
// but, by default is abstract is true
|
|
798
|
-
options.isAbstract = Object.
|
|
826
|
+
options.isAbstract = Object.hasOwn(options, "isAbstract") ? !!options.isAbstract : true;
|
|
799
827
|
return this.addObjectType(options);
|
|
800
828
|
}
|
|
801
829
|
|
|
802
830
|
// ---------------------------------------------------------------------------------------------------
|
|
803
|
-
/**
|
|
804
|
-
*
|
|
831
|
+
/**
|
|
832
|
+
*
|
|
805
833
|
*/
|
|
806
834
|
public addDataItem<T, DT extends DataType>(options: AddDataItemOptions): UADataItem<T, DT> {
|
|
807
835
|
const addressSpace = this.addressSpace;
|
|
@@ -859,7 +887,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
859
887
|
public addAnalogDataItem<T, DT extends DataType>(options: AddAnalogDataItemOptions): UAAnalogItem<T, DT> {
|
|
860
888
|
const addressSpace = this.addressSpace;
|
|
861
889
|
|
|
862
|
-
assert(Object.
|
|
890
|
+
assert(Object.hasOwn(options, "engineeringUnitsRange"), "expecting engineeringUnitsRange");
|
|
863
891
|
|
|
864
892
|
const dataType = options.dataType || "Number";
|
|
865
893
|
|
|
@@ -904,7 +932,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
904
932
|
const handler = variable.handle_semantic_changed.bind(variable);
|
|
905
933
|
euRange.on("value_changed", handler);
|
|
906
934
|
|
|
907
|
-
if (Object.
|
|
935
|
+
if (Object.hasOwn(options, "instrumentRange")) {
|
|
908
936
|
const instrumentRange = this.addVariable({
|
|
909
937
|
accessLevel: "CurrentRead | CurrentWrite",
|
|
910
938
|
browseName: { name: "InstrumentRange", namespaceIndex: 0 },
|
|
@@ -923,7 +951,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
923
951
|
}
|
|
924
952
|
(variable as any).acceptValueOutOfRange = options.acceptValueOutOfRange;
|
|
925
953
|
|
|
926
|
-
if (Object.
|
|
954
|
+
if (Object.hasOwn(options, "engineeringUnits")) {
|
|
927
955
|
const engineeringUnits = new EUInformation(options.engineeringUnits);
|
|
928
956
|
assert(engineeringUnits instanceof EUInformation, "expecting engineering units");
|
|
929
957
|
|
|
@@ -1033,8 +1061,8 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1033
1061
|
* @param options.value
|
|
1034
1062
|
*/
|
|
1035
1063
|
public addYArrayItem<DT extends DataType.Double | DataType.Float>(options: AddYArrayItemOptions): UAYArrayItemEx<DT> {
|
|
1036
|
-
assert(Object.
|
|
1037
|
-
assert(Object.
|
|
1064
|
+
assert(Object.hasOwn(options, "engineeringUnitsRange"), "expecting engineeringUnitsRange");
|
|
1065
|
+
assert(Object.hasOwn(options, "axisScaleType"), "expecting axisScaleType");
|
|
1038
1066
|
assert(options.xAxisDefinition !== null && typeof options.xAxisDefinition === "object", "expecting a xAxisDefinition");
|
|
1039
1067
|
|
|
1040
1068
|
const addressSpace = this.addressSpace;
|
|
@@ -1044,18 +1072,9 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1044
1072
|
throw new Error("expecting YArrayItemType to be defined , check nodeset xml file");
|
|
1045
1073
|
}
|
|
1046
1074
|
|
|
1047
|
-
|
|
1048
|
-
if (!options) {
|
|
1049
|
-
return resolveNodeId(DataType.Float);
|
|
1050
|
-
}
|
|
1051
|
-
if (Object.prototype.hasOwnProperty.call(options, "nodeId") || options instanceof BaseNodeImpl) {
|
|
1052
|
-
return (options as UADataType).nodeId;
|
|
1053
|
-
}
|
|
1054
|
-
return resolveNodeId(options as NodeIdLike);
|
|
1055
|
-
}
|
|
1056
|
-
const dataType = toNodeId(options.dataType as any);
|
|
1075
|
+
const dataType = toNodeId(options.dataType as unknown as NodeId) || toNodeId((options.value as Variant)?.dataType);
|
|
1057
1076
|
const optionals = [];
|
|
1058
|
-
if (Object.
|
|
1077
|
+
if (Object.hasOwn(options, "instrumentRange")) {
|
|
1059
1078
|
optionals.push("InstrumentRange");
|
|
1060
1079
|
}
|
|
1061
1080
|
const variable = YArrayItemType.instantiate({
|
|
@@ -1080,7 +1099,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1080
1099
|
})
|
|
1081
1100
|
);
|
|
1082
1101
|
|
|
1083
|
-
if (Object.
|
|
1102
|
+
if (Object.hasOwn(options, "instrumentRange") && variable.instrumentRange) {
|
|
1084
1103
|
variable.instrumentRange.setValueFromSource(
|
|
1085
1104
|
new Variant({
|
|
1086
1105
|
dataType: DataType.ExtensionObject,
|
|
@@ -1133,7 +1152,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1133
1152
|
parentObject !== null && typeof parentObject === "object" && parentObject instanceof BaseNodeImpl,
|
|
1134
1153
|
"expecting a valid parent object"
|
|
1135
1154
|
);
|
|
1136
|
-
assert(Object.
|
|
1155
|
+
assert(Object.hasOwn(options, "browseName"));
|
|
1137
1156
|
options.componentOf = parentObject;
|
|
1138
1157
|
|
|
1139
1158
|
const method = this._addMethod(options);
|
|
@@ -1277,14 +1296,13 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1277
1296
|
assert(Array.isArray(options.enumeration));
|
|
1278
1297
|
|
|
1279
1298
|
const addressSpace = this.addressSpace;
|
|
1280
|
-
|
|
1281
|
-
const enumerationType = addressSpace.findDataType("Enumeration")!;
|
|
1299
|
+
const enumerationType = addressSpace.findDataType("Enumeration") as UADataType;
|
|
1282
1300
|
assert(enumerationType.nodeId instanceof NodeId);
|
|
1283
1301
|
assert(enumerationType instanceof UADataTypeImpl);
|
|
1284
1302
|
const references = [{ referenceType: "HasSubtype", isForward: false, nodeId: enumerationType.nodeId }];
|
|
1285
1303
|
const opts = {
|
|
1286
1304
|
browseName: options.browseName,
|
|
1287
|
-
definition,
|
|
1305
|
+
definition: undefined,
|
|
1288
1306
|
description: coerceLocalizedText(options.description) || null,
|
|
1289
1307
|
displayName: options.displayName || null,
|
|
1290
1308
|
isAbstract: false,
|
|
@@ -1299,7 +1317,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1299
1317
|
if (typeof options.enumeration[0] === "string") {
|
|
1300
1318
|
const enumeration = options.enumeration as string[];
|
|
1301
1319
|
// enumeration is a array of string
|
|
1302
|
-
definition = enumeration.map((str: string,
|
|
1320
|
+
const definition = enumeration.map((str: string, _index: number) => coerceLocalizedText(str));
|
|
1303
1321
|
|
|
1304
1322
|
const value = new Variant({
|
|
1305
1323
|
arrayType: VariantArrayType.Array,
|
|
@@ -1341,7 +1359,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1341
1359
|
} else {
|
|
1342
1360
|
const enumeration = options.enumeration as EnumerationItem[];
|
|
1343
1361
|
// construct the definition object
|
|
1344
|
-
definition = enumeration.map((enumItem: EnumerationItem) => {
|
|
1362
|
+
const definition = enumeration.map((enumItem: EnumerationItem) => {
|
|
1345
1363
|
return new EnumValueType({
|
|
1346
1364
|
description: coerceLocalizedText(enumItem.description),
|
|
1347
1365
|
displayName: coerceLocalizedText(enumItem.displayName),
|
|
@@ -1368,7 +1386,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1368
1386
|
|
|
1369
1387
|
(enumType as any).$fullDefinition = new EnumDefinition({
|
|
1370
1388
|
fields: enumeration.map(
|
|
1371
|
-
(x: EnumerationItem,
|
|
1389
|
+
(x: EnumerationItem, _index: number) =>
|
|
1372
1390
|
new EnumField({
|
|
1373
1391
|
name: x.displayName.toString(),
|
|
1374
1392
|
|
|
@@ -1415,7 +1433,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1415
1433
|
// State and Transition
|
|
1416
1434
|
// -------------------------------------------------------------------------
|
|
1417
1435
|
/**
|
|
1418
|
-
|
|
1436
|
+
*/
|
|
1419
1437
|
public addState(
|
|
1420
1438
|
component: UAStateMachineEx,
|
|
1421
1439
|
stateName: QualifiedNameLike,
|
|
@@ -1469,30 +1487,30 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1469
1487
|
assert(_component.nodeClass === NodeClass.Object || _component.nodeClass === NodeClass.ObjectType);
|
|
1470
1488
|
assert(typeof fromState === "string");
|
|
1471
1489
|
assert(typeof toState === "string");
|
|
1472
|
-
assert(isFinite(transitionNumber));
|
|
1490
|
+
assert(Number.isFinite(transitionNumber));
|
|
1473
1491
|
|
|
1474
1492
|
const fromStateNode = _component.getComponentByName(fromState);
|
|
1475
1493
|
|
|
1476
1494
|
// c8 ignore next
|
|
1477
1495
|
if (!fromStateNode) {
|
|
1478
|
-
throw new Error(
|
|
1496
|
+
throw new Error(`Cannot find state with name ${fromState}`);
|
|
1479
1497
|
}
|
|
1480
|
-
assert(fromStateNode.browseName.name
|
|
1498
|
+
assert(fromStateNode.browseName.name?.toString() === fromState);
|
|
1481
1499
|
|
|
1482
1500
|
const toStateNode = _component.getComponentByName(toState);
|
|
1483
1501
|
|
|
1484
1502
|
// c8 ignore next
|
|
1485
1503
|
if (!toStateNode) {
|
|
1486
|
-
throw new Error(
|
|
1504
|
+
throw new Error(`Cannot find state with name ${toState}`);
|
|
1487
1505
|
}
|
|
1488
|
-
assert(toStateNode.browseName.name
|
|
1506
|
+
assert(toStateNode.browseName.name?.toString() === toState);
|
|
1489
1507
|
|
|
1490
1508
|
const transitionType = addressSpace.findObjectType("TransitionType");
|
|
1491
1509
|
if (!transitionType) {
|
|
1492
1510
|
throw new Error("Cannot find TransitionType");
|
|
1493
1511
|
}
|
|
1494
1512
|
|
|
1495
|
-
browseName = browseName || fromState
|
|
1513
|
+
browseName = browseName || `${fromState}To${toState}`; // "Transition";
|
|
1496
1514
|
|
|
1497
1515
|
const transition = transitionType.instantiate({
|
|
1498
1516
|
browseName,
|
|
@@ -1643,16 +1661,16 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1643
1661
|
if (node.nodeId.namespace !== this.index) {
|
|
1644
1662
|
throw new Error(
|
|
1645
1663
|
"node must belong to this namespace : " +
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1664
|
+
node.nodeId.toString() +
|
|
1665
|
+
" " +
|
|
1666
|
+
" node.browseName = " +
|
|
1667
|
+
node.browseName.toString() +
|
|
1668
|
+
" this.index = " +
|
|
1669
|
+
this.index
|
|
1652
1670
|
);
|
|
1653
1671
|
}
|
|
1654
1672
|
assert(node.nodeId.namespace === this.index, "node must belongs to this namespace");
|
|
1655
|
-
assert(Object.
|
|
1673
|
+
assert(Object.hasOwn(node, "browseName"), "Node must have a browseName");
|
|
1656
1674
|
|
|
1657
1675
|
const hashKey = _makeHashKey(node.nodeId);
|
|
1658
1676
|
|
|
@@ -1661,21 +1679,21 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1661
1679
|
const existingNode = this.findNode(node.nodeId)!;
|
|
1662
1680
|
throw new Error(
|
|
1663
1681
|
"node " +
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1682
|
+
node.browseName.toString() +
|
|
1683
|
+
" nodeId = " +
|
|
1684
|
+
node.nodeId.displayText() +
|
|
1685
|
+
" already registered " +
|
|
1686
|
+
node.nodeId.toString() +
|
|
1687
|
+
"\n" +
|
|
1688
|
+
" in namespace " +
|
|
1689
|
+
this.namespaceUri +
|
|
1690
|
+
" index = " +
|
|
1691
|
+
this.index +
|
|
1692
|
+
"\n" +
|
|
1693
|
+
"existing node = " +
|
|
1694
|
+
existingNode.toString() +
|
|
1695
|
+
"this parent : " +
|
|
1696
|
+
node.parentNodeId?.toString()
|
|
1679
1697
|
);
|
|
1680
1698
|
}
|
|
1681
1699
|
|
|
@@ -1717,7 +1735,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1717
1735
|
// ? (options.browseName.namespaceIndex === this.index): true,
|
|
1718
1736
|
// "Expecting browseName to have the same namespaceIndex as the namespace");
|
|
1719
1737
|
|
|
1720
|
-
options.description = coerceLocalizedText(options.description)
|
|
1738
|
+
options.description = coerceLocalizedText(options.description) || "";
|
|
1721
1739
|
|
|
1722
1740
|
// browseName adjustment
|
|
1723
1741
|
if (typeof options.browseName === "string") {
|
|
@@ -1738,15 +1756,15 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1738
1756
|
errorLog(
|
|
1739
1757
|
chalk.red.bold(
|
|
1740
1758
|
"Error: namespace index used at the front of the browseName " +
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1759
|
+
indexVerify +
|
|
1760
|
+
" do not match the index of the current namespace (" +
|
|
1761
|
+
this.index +
|
|
1762
|
+
")"
|
|
1745
1763
|
)
|
|
1746
1764
|
);
|
|
1747
1765
|
errorLog(
|
|
1748
1766
|
" Please fix your code so that the created node is inserted in the correct namespace," +
|
|
1749
|
-
|
|
1767
|
+
" please refer to the NodeOPCUA documentation"
|
|
1750
1768
|
);
|
|
1751
1769
|
}
|
|
1752
1770
|
}
|
|
@@ -1760,27 +1778,29 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1760
1778
|
// ------------- set display name
|
|
1761
1779
|
if (!options.displayName) {
|
|
1762
1780
|
assert(typeof options.browseName.name === "string");
|
|
1763
|
-
options.displayName = coerceLocalizedText(options.browseName.name)
|
|
1781
|
+
options.displayName = coerceLocalizedText(options.browseName.name || "");
|
|
1764
1782
|
}
|
|
1765
|
-
if (!options.nodeClass || options.nodeClass
|
|
1783
|
+
if (!options.nodeClass || options.nodeClass === undefined) {
|
|
1766
1784
|
throw new Error("nodeclass must be specified");
|
|
1767
1785
|
}
|
|
1768
1786
|
// --- nodeId adjustment
|
|
1769
|
-
options.nodeId = this.constructNodeId(options as ConstructNodeIdOptions)
|
|
1787
|
+
options.nodeId = this.constructNodeId(options as ConstructNodeIdOptions);
|
|
1770
1788
|
dumpIf(!options.nodeId, options); // missing node Id
|
|
1771
1789
|
assert(options.nodeId instanceof NodeId);
|
|
1772
1790
|
|
|
1773
1791
|
// assert(options.browseName.namespaceIndex === this.index,"Expecting browseName to have
|
|
1774
1792
|
// the same namespaceIndex as the namespace");
|
|
1775
1793
|
|
|
1776
|
-
const Constructor = _constructors_map[NodeClass[options.nodeClass
|
|
1794
|
+
const Constructor = _constructors_map[NodeClass[options.nodeClass] as keyof typeof _constructors_map];
|
|
1777
1795
|
|
|
1778
1796
|
if (!Constructor) {
|
|
1779
|
-
throw new Error(
|
|
1797
|
+
throw new Error(` missing constructor for NodeClass ${NodeClass[options.nodeClass]}`);
|
|
1780
1798
|
}
|
|
1781
1799
|
|
|
1782
|
-
options.addressSpace = this.addressSpace;
|
|
1783
|
-
|
|
1800
|
+
options.addressSpace = this.addressSpace as AddressSpacePrivate;
|
|
1801
|
+
|
|
1802
|
+
// biome-ignore lint/suspicious/noExplicitAny: to fix later
|
|
1803
|
+
const node = new Constructor(options as any);
|
|
1784
1804
|
this._register(node);
|
|
1785
1805
|
|
|
1786
1806
|
// object shall now be registered
|
|
@@ -1797,7 +1817,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1797
1817
|
const hashKey = _makeHashKey(node.nodeId);
|
|
1798
1818
|
// c8 ignore next
|
|
1799
1819
|
if (!this._nodeid_index.has(hashKey)) {
|
|
1800
|
-
throw new Error(
|
|
1820
|
+
throw new Error(`deleteNode : nodeId ${node.nodeId.displayText()} is not registered ${node.nodeId.toString()}`);
|
|
1801
1821
|
}
|
|
1802
1822
|
switch (node.nodeClass) {
|
|
1803
1823
|
case NodeClass.ObjectType:
|
|
@@ -1823,7 +1843,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1823
1843
|
|
|
1824
1844
|
// --- Private stuff
|
|
1825
1845
|
|
|
1826
|
-
private _addObjectOrVariableType<
|
|
1846
|
+
private _addObjectOrVariableType<_T>(
|
|
1827
1847
|
options1: AddBaseNodeOptions,
|
|
1828
1848
|
topMostBaseType: string,
|
|
1829
1849
|
nodeClass: NodeClass.ObjectType | NodeClass.VariableType
|
|
@@ -1837,7 +1857,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1837
1857
|
assert(!options.nodeClass);
|
|
1838
1858
|
assert(options.browseName);
|
|
1839
1859
|
assert(typeof options.browseName === "string");
|
|
1840
|
-
if (Object.
|
|
1860
|
+
if (Object.hasOwn(options, "references")) {
|
|
1841
1861
|
throw new Error("options.references should not be provided, use options.subtypeOf instead");
|
|
1842
1862
|
}
|
|
1843
1863
|
const references: UAReference[] = [];
|
|
@@ -1845,7 +1865,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1845
1865
|
function process_subtypeOf_options(this: NamespaceImpl, options2: any, references1: AddReferenceOpts[]) {
|
|
1846
1866
|
// check common misspelling mistake
|
|
1847
1867
|
assert(!options2.subTypeOf, "misspell error : it should be 'subtypeOf' instead");
|
|
1848
|
-
if (Object.
|
|
1868
|
+
if (Object.hasOwn(options2, "hasTypeDefinition")) {
|
|
1849
1869
|
throw new Error("hasTypeDefinition option is invalid. Do you mean typeDefinition instead ?");
|
|
1850
1870
|
}
|
|
1851
1871
|
assert(!options2.typeDefinition, " do you mean subtypeOf ?");
|
|
@@ -1901,16 +1921,16 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1901
1921
|
|
|
1902
1922
|
private _registerObjectType(node: UAObjectType) {
|
|
1903
1923
|
assert(this.index === node.nodeId.namespace);
|
|
1904
|
-
const key = node.browseName.name
|
|
1924
|
+
const key = node.browseName.name || "";
|
|
1905
1925
|
if (this._objectTypeMap.has(key)) {
|
|
1906
|
-
throw new Error(
|
|
1926
|
+
throw new Error(` UAObjectType already declared ${node.browseName.toString()} ${node.nodeId.toString()}`);
|
|
1907
1927
|
}
|
|
1908
1928
|
this._objectTypeMap.set(key, node);
|
|
1909
1929
|
}
|
|
1910
1930
|
|
|
1911
1931
|
private _registerVariableType(node: UAVariableType) {
|
|
1912
1932
|
assert(this.index === node.nodeId.namespace);
|
|
1913
|
-
const key = node.browseName.name
|
|
1933
|
+
const key = node.browseName.name || "";
|
|
1914
1934
|
assert(!this._variableTypeMap.has(key), " UAVariableType already declared");
|
|
1915
1935
|
this._variableTypeMap.set(key, node);
|
|
1916
1936
|
}
|
|
@@ -1918,26 +1938,26 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1918
1938
|
private _registerReferenceType(node: UAReferenceType) {
|
|
1919
1939
|
assert(this.index === node.nodeId.namespace);
|
|
1920
1940
|
assert(node.browseName instanceof QualifiedName);
|
|
1921
|
-
const key: string = node.browseName.name
|
|
1941
|
+
const key: string = node.browseName.name || "";
|
|
1922
1942
|
this._referenceTypeMap.set(key, node);
|
|
1923
|
-
this._referenceTypeMapInv.set(node.inverseName.text
|
|
1943
|
+
this._referenceTypeMapInv.set(node.inverseName.text || "", node);
|
|
1924
1944
|
}
|
|
1925
1945
|
|
|
1926
1946
|
private _registerDataType(node: UADataType) {
|
|
1927
1947
|
assert(this.index === node.nodeId.namespace);
|
|
1928
|
-
const key = node.browseName.name
|
|
1948
|
+
const key = node.browseName.name || "";
|
|
1929
1949
|
assert(node.browseName instanceof QualifiedName);
|
|
1930
1950
|
assert(!this._dataTypeMap.has(key), " DataType already declared");
|
|
1931
1951
|
this._dataTypeMap.set(key, node);
|
|
1932
1952
|
}
|
|
1933
1953
|
|
|
1934
1954
|
private _unregisterObjectType(node: UAObjectType): void {
|
|
1935
|
-
const key = node.browseName.name
|
|
1955
|
+
const key = node.browseName.name || "";
|
|
1936
1956
|
this._objectTypeMap.delete(key);
|
|
1937
1957
|
}
|
|
1938
1958
|
|
|
1939
1959
|
private _unregisterVariableType(node: UAVariableType): void {
|
|
1940
|
-
const key = node.browseName.name
|
|
1960
|
+
const key = node.browseName.name || "";
|
|
1941
1961
|
this._variableTypeMap.delete(key);
|
|
1942
1962
|
}
|
|
1943
1963
|
|
|
@@ -1953,13 +1973,13 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1953
1973
|
}
|
|
1954
1974
|
const baseDataVariableTypeId = baseDataVariableType.nodeId;
|
|
1955
1975
|
|
|
1956
|
-
assert(Object.
|
|
1957
|
-
assert(Object.
|
|
1976
|
+
assert(Object.hasOwn(options, "browseName"), "options.browseName must be provided");
|
|
1977
|
+
assert(Object.hasOwn(options, "dataType"), "options.dataType must be provided");
|
|
1958
1978
|
|
|
1959
1979
|
options.historizing = !!options.historizing;
|
|
1960
1980
|
|
|
1961
1981
|
// c8 ignore next
|
|
1962
|
-
if (Object.
|
|
1982
|
+
if (Object.hasOwn(options, "hasTypeDefinition")) {
|
|
1963
1983
|
throw new Error("hasTypeDefinition option is invalid. Do you mean typeDefinition instead ?");
|
|
1964
1984
|
}
|
|
1965
1985
|
// ------------------------------------------ TypeDefinition
|
|
@@ -1976,14 +1996,14 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1976
1996
|
assert(typeDefinition instanceof NodeId);
|
|
1977
1997
|
|
|
1978
1998
|
// ------------------------------------------ DataType
|
|
1979
|
-
options.dataType = addressSpace._coerce_DataType(options.dataType
|
|
1999
|
+
options.dataType = addressSpace._coerce_DataType(options.dataType || DataType.Null);
|
|
1980
2000
|
|
|
1981
2001
|
options.valueRank = isNullOrUndefined(options.valueRank)
|
|
1982
2002
|
? options.arrayDimensions
|
|
1983
2003
|
? options.arrayDimensions.length
|
|
1984
2004
|
: -1
|
|
1985
2005
|
: options.valueRank;
|
|
1986
|
-
assert(typeof options.valueRank === "number" && isFinite(options.valueRank
|
|
2006
|
+
assert(typeof options.valueRank === "number" && Number.isFinite(options.valueRank));
|
|
1987
2007
|
|
|
1988
2008
|
options.arrayDimensions = options.arrayDimensions || null;
|
|
1989
2009
|
assert(options.arrayDimensions === null || Array.isArray(options.arrayDimensions));
|
|
@@ -1999,7 +2019,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1999
2019
|
warningLog(
|
|
2000
2020
|
"[NODE-OPCUA-W30",
|
|
2001
2021
|
"namespace#addVariable a getter has been specified and minimumSamplingInterval is missing.\nMinimumSamplingInterval has been adjusted to 1000 ms\nvariable = " +
|
|
2002
|
-
|
|
2022
|
+
options?.browseName?.toString()
|
|
2003
2023
|
);
|
|
2004
2024
|
options.minimumSamplingInterval = 1000;
|
|
2005
2025
|
}
|
|
@@ -2067,7 +2087,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
2067
2087
|
}
|
|
2068
2088
|
}
|
|
2069
2089
|
|
|
2070
|
-
const _constructors_map:
|
|
2090
|
+
const _constructors_map: Record<keyof Omit<typeof NodeClass, "Unspecified">, typeof BaseNodeImpl> = {
|
|
2071
2091
|
DataType: UADataTypeImpl,
|
|
2072
2092
|
Method: UAMethodImpl,
|
|
2073
2093
|
Object: UAObjectImpl,
|
|
@@ -2088,7 +2108,7 @@ const _constructors_map: any = {
|
|
|
2088
2108
|
*/
|
|
2089
2109
|
function _coerce_parent(
|
|
2090
2110
|
addressSpace: AddressSpacePrivate,
|
|
2091
|
-
value: null | string | BaseNode| undefined | NodeIdLike,
|
|
2111
|
+
value: null | string | BaseNode | undefined | NodeIdLike,
|
|
2092
2112
|
coerceFunc: (data: string | NodeId | BaseNode) => BaseNode | null
|
|
2093
2113
|
): BaseNode | null {
|
|
2094
2114
|
assert(typeof coerceFunc === "function");
|
|
@@ -2129,8 +2149,18 @@ function _handle_event_hierarchy_parent(
|
|
|
2129
2149
|
});
|
|
2130
2150
|
}
|
|
2131
2151
|
}
|
|
2132
|
-
|
|
2133
|
-
|
|
2152
|
+
interface HandleHierarchyParentOptions {
|
|
2153
|
+
addInOf?: NodeIdLike | BaseNode | null | undefined;
|
|
2154
|
+
componentOf?: NodeIdLike | BaseNode | null | undefined;
|
|
2155
|
+
propertyOf?: NodeIdLike | BaseNode | null | undefined;
|
|
2156
|
+
organizedBy?: NodeIdLike | BaseNode | null | undefined;
|
|
2157
|
+
encodingOf?: NodeIdLike | BaseNode | null | undefined;
|
|
2158
|
+
}
|
|
2159
|
+
export function _handle_hierarchy_parent(
|
|
2160
|
+
addressSpace: AddressSpacePrivate,
|
|
2161
|
+
references: AddReferenceOpts[],
|
|
2162
|
+
options: HandleHierarchyParentOptions
|
|
2163
|
+
): void {
|
|
2134
2164
|
options.addInOf = _coerce_parent(addressSpace, options.addInOf, addressSpace._coerceNode);
|
|
2135
2165
|
options.componentOf = _coerce_parent(addressSpace, options.componentOf, addressSpace._coerceNode);
|
|
2136
2166
|
options.propertyOf = _coerce_parent(addressSpace, options.propertyOf, addressSpace._coerceNode);
|
|
@@ -2141,9 +2171,10 @@ export function _handle_hierarchy_parent(addressSpace: AddressSpacePrivate, refe
|
|
|
2141
2171
|
assert(!options.componentOf);
|
|
2142
2172
|
assert(!options.propertyOf);
|
|
2143
2173
|
assert(!options.organizedBy);
|
|
2144
|
-
assert(
|
|
2174
|
+
assert(
|
|
2175
|
+
options.addInOf.nodeClass === NodeClass.Object || options.addInOf.nodeClass === NodeClass.ObjectType,
|
|
2145
2176
|
"addInOf must be of nodeClass Object or ObjectType"
|
|
2146
|
-
);
|
|
2177
|
+
);
|
|
2147
2178
|
references.push({
|
|
2148
2179
|
isForward: false,
|
|
2149
2180
|
nodeId: options.addInOf.nodeId,
|
|
@@ -2192,7 +2223,7 @@ export function _handle_hierarchy_parent(addressSpace: AddressSpacePrivate, refe
|
|
|
2192
2223
|
referenceType: "Organizes"
|
|
2193
2224
|
});
|
|
2194
2225
|
}
|
|
2195
|
-
|
|
2226
|
+
|
|
2196
2227
|
if (options.encodingOf) {
|
|
2197
2228
|
// parent must be a DataType
|
|
2198
2229
|
assert(options.encodingOf.nodeClass === NodeClass.DataType, "encodingOf must be toward a DataType");
|
|
@@ -2205,9 +2236,9 @@ export function _handle_hierarchy_parent(addressSpace: AddressSpacePrivate, refe
|
|
|
2205
2236
|
}
|
|
2206
2237
|
|
|
2207
2238
|
function _copy_reference(reference: UAReference | AddReferenceOpts): AddReferenceOpts {
|
|
2208
|
-
assert(Object.
|
|
2209
|
-
assert(Object.
|
|
2210
|
-
assert(Object.
|
|
2239
|
+
assert(Object.hasOwn(reference, "referenceType"));
|
|
2240
|
+
assert(Object.hasOwn(reference, "isForward"));
|
|
2241
|
+
assert(Object.hasOwn(reference, "nodeId"));
|
|
2211
2242
|
assert(reference.nodeId instanceof NodeId);
|
|
2212
2243
|
return {
|
|
2213
2244
|
isForward: reference.isForward,
|
|
@@ -2232,12 +2263,12 @@ export function isNonEmptyQualifiedName(browseName: QualifiedNameLike): boolean
|
|
|
2232
2263
|
browseName = new QualifiedName(browseName);
|
|
2233
2264
|
}
|
|
2234
2265
|
assert(browseName instanceof QualifiedName);
|
|
2235
|
-
return browseName.name
|
|
2266
|
+
return (browseName.name?.length || 0) > 0;
|
|
2236
2267
|
}
|
|
2237
2268
|
|
|
2238
2269
|
function _create_node_version_if_needed(node: BaseNode, options: { nodeVersion?: string }) {
|
|
2239
2270
|
assert(options);
|
|
2240
|
-
if (typeof options.nodeVersion
|
|
2271
|
+
if (typeof options.nodeVersion === "string") {
|
|
2241
2272
|
assert(node.nodeClass === NodeClass.Variable || node.nodeClass === NodeClass.Object);
|
|
2242
2273
|
// c8 ignore next
|
|
2243
2274
|
if (node.getNodeVersion()) {
|