node-opcua-address-space 2.86.1 → 2.88.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/LICENSE +1 -1
- package/dist/source/index.d.ts +1 -0
- package/dist/source/index.js +1 -0
- package/dist/source/index.js.map +1 -1
- package/dist/src/base_node_private.js +7 -6
- package/dist/src/base_node_private.js.map +1 -1
- package/dist/src/extension_object_array_node.d.ts +2 -40
- package/dist/src/extension_object_array_node.js +9 -45
- package/dist/src/extension_object_array_node.js.map +1 -1
- package/dist/src/idx_iterator.d.ts +8 -0
- package/dist/src/idx_iterator.js +51 -0
- package/dist/src/idx_iterator.js.map +1 -0
- package/dist/src/index_current.d.ts +1 -0
- package/dist/src/index_current.js +1 -0
- package/dist/src/index_current.js.map +1 -1
- package/dist/src/namespace_impl.js +7 -4
- package/dist/src/namespace_impl.js.map +1 -1
- package/dist/src/nodeid_manager.d.ts +6 -6
- package/dist/src/nodeid_manager.js +71 -97
- package/dist/src/nodeid_manager.js.map +1 -1
- package/dist/src/nodeset_tools/construct_namespace_dependency.d.ts +14 -0
- package/dist/src/nodeset_tools/construct_namespace_dependency.js +21 -1
- package/dist/src/nodeset_tools/construct_namespace_dependency.js.map +1 -1
- package/dist/src/nodeset_tools/nodeset_to_xml.d.ts +1 -3
- package/dist/src/nodeset_tools/nodeset_to_xml.js +24 -10
- package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
- package/dist/src/private_namespace.d.ts +5 -0
- package/dist/src/private_namespace.js +20 -0
- package/dist/src/private_namespace.js.map +1 -0
- package/dist/src/ua_variable_impl.d.ts +11 -9
- package/dist/src/ua_variable_impl.js +23 -3
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/dist/src/ua_variable_impl_ext_obj.d.ts +3 -1
- package/dist/src/ua_variable_impl_ext_obj.js +152 -20
- package/dist/src/ua_variable_impl_ext_obj.js.map +1 -1
- package/package.json +40 -40
- package/source/index.ts +1 -0
- package/src/base_node_private.ts +52 -48
- package/src/extension_object_array_node.ts +15 -54
- package/src/idx_iterator.ts +52 -0
- package/src/index_current.ts +1 -0
- package/src/namespace_impl.ts +23 -20
- package/src/nodeid_manager.ts +84 -100
- package/src/nodeset_tools/construct_namespace_dependency.ts +30 -9
- package/src/nodeset_tools/nodeset_to_xml.ts +30 -14
- package/src/private_namespace.ts +18 -0
- package/src/ua_variable_impl.ts +34 -13
- package/src/ua_variable_impl_ext_obj.ts +186 -33
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as chalk from "chalk";
|
|
2
2
|
import assert from "node-opcua-assert";
|
|
3
|
-
import { BindExtensionObjectOptions, UADataType, UAVariable, UAVariableType } from "node-opcua-address-space-base";
|
|
4
|
-
import { NodeClass } from "node-opcua-data-model";
|
|
5
|
-
import { getCurrentClock, PreciseClock } from "node-opcua-date-time";
|
|
3
|
+
import { BindExtensionObjectOptions, UADataType, UADynamicVariableArray, UAVariable, UAVariableType } from "node-opcua-address-space-base";
|
|
4
|
+
import { coerceQualifiedName, NodeClass } from "node-opcua-data-model";
|
|
5
|
+
import { getCurrentClock, PreciseClock, DateWithPicoseconds, coerceClock } from "node-opcua-date-time";
|
|
6
6
|
import { DataValue } from "node-opcua-data-value";
|
|
7
7
|
import { make_debugLog, make_warningLog, checkDebugFlag, make_errorLog } from "node-opcua-debug";
|
|
8
8
|
import { ExtensionObject } from "node-opcua-extension-object";
|
|
9
|
-
import { NodeId } from "node-opcua-nodeid";
|
|
9
|
+
import { coerceNodeId, NodeId, NodeIdType } from "node-opcua-nodeid";
|
|
10
10
|
import { StatusCodes, CallbackT, StatusCode } from "node-opcua-status-code";
|
|
11
11
|
import { StructureField } from "node-opcua-types";
|
|
12
12
|
import { lowerFirstLetter } from "node-opcua-utils";
|
|
@@ -15,6 +15,9 @@ import { DataType, Variant, VariantLike, VariantArrayType } from "node-opcua-var
|
|
|
15
15
|
import { valueRankToString } from "./base_node_private";
|
|
16
16
|
import { UAVariableImpl } from "./ua_variable_impl";
|
|
17
17
|
import { UADataTypeImpl } from "./ua_data_type_impl";
|
|
18
|
+
import { bindExtObjArrayNode } from "./extension_object_array_node";
|
|
19
|
+
import { IndexIterator } from "./idx_iterator";
|
|
20
|
+
import { DateTime } from "node-opcua-basic-types";
|
|
18
21
|
|
|
19
22
|
const doDebug = checkDebugFlag(__filename);
|
|
20
23
|
const debugLog = make_debugLog(__filename);
|
|
@@ -114,7 +117,7 @@ function propagateTouchValueDownward(self: UAVariableImpl, now: PreciseClock): v
|
|
|
114
117
|
}
|
|
115
118
|
}
|
|
116
119
|
|
|
117
|
-
export function _setExtensionObject(self: UAVariableImpl, ext: ExtensionObject | ExtensionObject[]): void {
|
|
120
|
+
export function _setExtensionObject(self: UAVariableImpl, ext: ExtensionObject | ExtensionObject[], sourceTimestamp?: PreciseClock): void {
|
|
118
121
|
// assert(!(ext as any).$isProxy, "internal error ! ExtensionObject has already been proxied !");
|
|
119
122
|
if (Array.isArray(ext)) {
|
|
120
123
|
assert(self.valueRank === 1, "Only Array is supported for the time being");
|
|
@@ -133,7 +136,7 @@ export function _setExtensionObject(self: UAVariableImpl, ext: ExtensionObject |
|
|
|
133
136
|
self.$dataValue.statusCode = StatusCodes.Good;
|
|
134
137
|
}
|
|
135
138
|
|
|
136
|
-
const now = getCurrentClock();
|
|
139
|
+
const now = sourceTimestamp || getCurrentClock();
|
|
137
140
|
propagateTouchValueUpward(self, now);
|
|
138
141
|
propagateTouchValueDownward(self, now);
|
|
139
142
|
}
|
|
@@ -193,7 +196,10 @@ function getOrCreateProperty(
|
|
|
193
196
|
browseName: { namespaceIndex: structureNamespace, name: field.name!.toString() },
|
|
194
197
|
componentOf: variableNode,
|
|
195
198
|
dataType: field.dataType,
|
|
196
|
-
minimumSamplingInterval: variableNode.minimumSamplingInterval
|
|
199
|
+
minimumSamplingInterval: variableNode.minimumSamplingInterval,
|
|
200
|
+
accessLevel: variableNode.accessLevel,
|
|
201
|
+
accessRestrictions: variableNode.accessRestrictions,
|
|
202
|
+
rolePermissions: variableNode.rolePermissions
|
|
197
203
|
}) as UAVariableImpl;
|
|
198
204
|
assert(property.minimumSamplingInterval === variableNode.minimumSamplingInterval);
|
|
199
205
|
}
|
|
@@ -226,17 +232,46 @@ function bindProperty(variableNode: UAVariableImpl, propertyNode: UAVariableImpl
|
|
|
226
232
|
return new DataValue(propertyNode.$dataValue);
|
|
227
233
|
},
|
|
228
234
|
timestamped_set: (_dataValue: DataValue, callback: CallbackT<StatusCode>) => {
|
|
229
|
-
|
|
235
|
+
|
|
236
|
+
propertyNode.setValueFromSource(_dataValue.value, _dataValue.statusCode, _dataValue.sourceTimestamp || new Date());
|
|
237
|
+
// callback(null, StatusCodes.BadNotWritable);
|
|
238
|
+
callback(null, StatusCodes.Good);
|
|
230
239
|
}
|
|
231
240
|
},
|
|
232
241
|
true
|
|
233
242
|
);
|
|
234
243
|
}
|
|
235
244
|
|
|
245
|
+
|
|
246
|
+
function _initial_setup(variableNode: UAVariableImpl) {
|
|
247
|
+
const dataValue = variableNode.readValue();
|
|
248
|
+
const extObj = dataValue.value.value;
|
|
249
|
+
if (extObj instanceof ExtensionObject) {
|
|
250
|
+
variableNode.bindExtensionObject(extObj, { createMissingProp: true, force: true });
|
|
251
|
+
} else if (extObj instanceof Array) {
|
|
252
|
+
if (dataValue.value.arrayType === VariantArrayType.Array) {
|
|
253
|
+
variableNode.bindExtensionObjectArray(extObj, { createMissingProp: true, force: true });
|
|
254
|
+
} else if (dataValue.value.arrayType === VariantArrayType.Matrix) {
|
|
255
|
+
_bindExtensionObjectMatrix(variableNode, extObj, { createMissingProp: true, force: true });
|
|
256
|
+
} else {
|
|
257
|
+
throw new Error("Internal Error, unexpected case");
|
|
258
|
+
}
|
|
259
|
+
} else {
|
|
260
|
+
const msg = `variableNode ${variableNode.browseName.toString()} doesn't have $extensionObject property`;
|
|
261
|
+
errorLog(msg);
|
|
262
|
+
errorLog(dataValue.toString());
|
|
263
|
+
throw new Error(msg);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
236
266
|
export function _installExtensionObjectBindingOnProperties(
|
|
237
267
|
variableNode: UAVariableImpl,
|
|
238
268
|
options: BindExtensionObjectOptions
|
|
239
269
|
): void {
|
|
270
|
+
|
|
271
|
+
if (!variableNode.$extensionObject) {
|
|
272
|
+
_initial_setup(variableNode);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
240
275
|
const addressSpace = variableNode.addressSpace;
|
|
241
276
|
const dt = variableNode.getDataTypeNode();
|
|
242
277
|
const definition = dt.getStructureDefinition();
|
|
@@ -256,7 +291,12 @@ export function _installExtensionObjectBindingOnProperties(
|
|
|
256
291
|
continue;
|
|
257
292
|
}
|
|
258
293
|
propertyNode.$dataValue.statusCode = StatusCodes.Good;
|
|
259
|
-
propertyNode.
|
|
294
|
+
propertyNode.$dataValue.sourceTimestamp = variableNode.$dataValue.sourceTimestamp;
|
|
295
|
+
propertyNode.$dataValue.sourcePicoseconds = variableNode.$dataValue.sourcePicoseconds;
|
|
296
|
+
propertyNode.$dataValue.serverTimestamp = variableNode.$dataValue.serverTimestamp;
|
|
297
|
+
propertyNode.$dataValue.serverPicoseconds = variableNode.$dataValue.serverPicoseconds;
|
|
298
|
+
|
|
299
|
+
//xx propertyNode.touchValue();
|
|
260
300
|
|
|
261
301
|
const basicDataType = addressSpace.findCorrespondingBasicDataType(field.dataType);
|
|
262
302
|
|
|
@@ -322,36 +362,43 @@ export function _installExtensionObjectBindingOnProperties(
|
|
|
322
362
|
}
|
|
323
363
|
}
|
|
324
364
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
self: UAVariableImpl,
|
|
328
|
-
optionalExtensionObject?: ExtensionObject | ExtensionObject[],
|
|
329
|
-
options?: BindExtensionObjectOptions
|
|
330
|
-
): ExtensionObject | ExtensionObject[] | null {
|
|
331
|
-
options = options || { createMissingProp: false };
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const addressSpace = self.addressSpace;
|
|
365
|
+
function isVariableContainingExtensionObject(uaVariable: UAVariableImpl): boolean {
|
|
366
|
+
const addressSpace = uaVariable.addressSpace;
|
|
335
367
|
const structure = addressSpace.findDataType("Structure");
|
|
336
|
-
let extensionObject_;
|
|
337
368
|
|
|
338
369
|
if (!structure) {
|
|
339
370
|
// the addressSpace is limited and doesn't provide extension object
|
|
340
371
|
// bindExtensionObject cannot be performed and shall finish here.
|
|
341
|
-
return
|
|
372
|
+
return false;
|
|
342
373
|
}
|
|
343
374
|
|
|
344
375
|
assert(structure.browseName.toString() === "Structure", "expecting DataType Structure to be in IAddressSpace");
|
|
345
376
|
|
|
346
|
-
const dt =
|
|
377
|
+
const dt = uaVariable.getDataTypeNode() as UADataTypeImpl;
|
|
347
378
|
if (!dt.isSupertypeOf(structure)) {
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
return true;
|
|
382
|
+
|
|
383
|
+
}
|
|
384
|
+
// eslint-disable-next-line complexity
|
|
385
|
+
export function _bindExtensionObject(
|
|
386
|
+
self: UAVariableImpl,
|
|
387
|
+
optionalExtensionObject?: ExtensionObject | ExtensionObject[],
|
|
388
|
+
options?: BindExtensionObjectOptions
|
|
389
|
+
): ExtensionObject | ExtensionObject[] | null {
|
|
390
|
+
options = options || { createMissingProp: false };
|
|
391
|
+
|
|
392
|
+
if (!isVariableContainingExtensionObject(self)) {
|
|
348
393
|
return null;
|
|
349
394
|
}
|
|
395
|
+
const addressSpace = self.addressSpace;
|
|
396
|
+
let extensionObject_;
|
|
350
397
|
|
|
351
|
-
if (self.valueRank !== -1 && self.valueRank !==1) {
|
|
398
|
+
if (self.valueRank !== -1 && self.valueRank !== 1) {
|
|
352
399
|
throw new Error("Cannot bind an extension object here, valueRank must be scalar (-1) or one-dimensional (1)");
|
|
353
400
|
}
|
|
354
|
-
|
|
401
|
+
|
|
355
402
|
// istanbul ignore next
|
|
356
403
|
if (doDebug) {
|
|
357
404
|
debugLog(" ------------------------------ binding ", self.browseName.toString(), self.nodeId.toString());
|
|
@@ -365,6 +412,7 @@ export function _bindExtensionObject(
|
|
|
365
412
|
) {
|
|
366
413
|
const parentDataType = (self.parent as UAVariable | UAVariableType).dataType;
|
|
367
414
|
const dataTypeNode = addressSpace.findNode(parentDataType) as UADataType;
|
|
415
|
+
const structure = addressSpace.findDataType("Structure")!;
|
|
368
416
|
// istanbul ignore next
|
|
369
417
|
if (dataTypeNode && dataTypeNode.isSupertypeOf(structure)) {
|
|
370
418
|
// warningLog(
|
|
@@ -392,9 +440,9 @@ export function _bindExtensionObject(
|
|
|
392
440
|
warningLog(self.$extensionObject?.toString());
|
|
393
441
|
throw new Error(
|
|
394
442
|
"bindExtensionObject: $extensionObject is incorrect: we are expecting a " +
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
443
|
+
self.dataType.toString({ addressSpace: self.addressSpace }) +
|
|
444
|
+
" but we got a " +
|
|
445
|
+
self.$extensionObject?.constructor.name
|
|
398
446
|
);
|
|
399
447
|
}
|
|
400
448
|
return self.$extensionObject;
|
|
@@ -422,6 +470,10 @@ export function _bindExtensionObject(
|
|
|
422
470
|
return self.$extensionObject;
|
|
423
471
|
|
|
424
472
|
function innerBindExtensionObject() {
|
|
473
|
+
const makePreciseClock = (sourceTimestamp: DateTime, picoseconds?: number): PreciseClock =>
|
|
474
|
+
({ timestamp: sourceTimestamp as DateWithPicoseconds, picoseconds: picoseconds || 0 });
|
|
475
|
+
|
|
476
|
+
|
|
425
477
|
if (s.value && (s.value.dataType === DataType.Null || (s.value.dataType === DataType.ExtensionObject && !s.value.value))) {
|
|
426
478
|
if (self.valueRank === -1 /** Scalar */) {
|
|
427
479
|
// create a structure and bind it
|
|
@@ -439,13 +491,16 @@ export function _bindExtensionObject(
|
|
|
439
491
|
if (!self.checkExtensionObjectIsCorrect(ext)) {
|
|
440
492
|
return callback(null, StatusCodes.BadInvalidArgument);
|
|
441
493
|
}
|
|
442
|
-
|
|
494
|
+
const sourceTime = coerceClock(dataValue.sourceTimestamp, dataValue.sourcePicoseconds);
|
|
495
|
+
_setExtensionObject(self, ext, sourceTime);
|
|
443
496
|
callback(null, StatusCodes.Good);
|
|
444
497
|
}
|
|
445
498
|
},
|
|
446
499
|
true
|
|
447
500
|
);
|
|
448
|
-
|
|
501
|
+
const sourceTime = coerceClock(self.$dataValue.sourceTimestamp, self.$dataValue.sourcePicoseconds);
|
|
502
|
+
_setExtensionObject(self, extensionObject_, sourceTime);
|
|
503
|
+
|
|
449
504
|
} else if (self.valueRank === 1 /** Array */) {
|
|
450
505
|
// create a structure and bind it
|
|
451
506
|
|
|
@@ -462,17 +517,19 @@ export function _bindExtensionObject(
|
|
|
462
517
|
return d;
|
|
463
518
|
},
|
|
464
519
|
timestamped_set(dataValue: DataValue, callback: CallbackT<StatusCode>) {
|
|
465
|
-
const
|
|
466
|
-
if (!self.checkExtensionObjectIsCorrect(
|
|
520
|
+
const extensionObjectArray = dataValue.value.value;
|
|
521
|
+
if (!self.checkExtensionObjectIsCorrect(extensionObjectArray)) {
|
|
467
522
|
return callback(null, StatusCodes.BadInvalidArgument);
|
|
468
523
|
}
|
|
469
|
-
|
|
524
|
+
const sourceTime = coerceClock(dataValue.sourceTimestamp, dataValue.sourcePicoseconds);
|
|
525
|
+
_setExtensionObject(self, extensionObjectArray, sourceTime);
|
|
470
526
|
callback(null, StatusCodes.Good);
|
|
471
527
|
}
|
|
472
528
|
},
|
|
473
529
|
true
|
|
474
530
|
);
|
|
475
|
-
|
|
531
|
+
const sourceTime = coerceClock(self.$dataValue.sourceTimestamp, self.$dataValue.sourcePicoseconds);
|
|
532
|
+
_setExtensionObject(self, extensionObject_, sourceTime);
|
|
476
533
|
} else {
|
|
477
534
|
errorLog(self.toString());
|
|
478
535
|
errorLog("Unsupported case ! valueRank= ", self.valueRank);
|
|
@@ -488,6 +545,102 @@ export function _bindExtensionObject(
|
|
|
488
545
|
}
|
|
489
546
|
}
|
|
490
547
|
|
|
548
|
+
const getIndexAsText = (index: number | number[]): string => {
|
|
549
|
+
if (typeof index === "number")
|
|
550
|
+
return `${index}`;
|
|
551
|
+
return `${index.map((a) => a.toString()).join(",")}`;
|
|
552
|
+
}
|
|
553
|
+
const composeBrowseNameAndNodeId = (uaVariable: UAVariable, indexes: number[]) => {
|
|
554
|
+
const iAsText = getIndexAsText(indexes);
|
|
555
|
+
const browseName = coerceQualifiedName(iAsText);
|
|
556
|
+
let nodeId: NodeId | undefined;
|
|
557
|
+
if (uaVariable.nodeId.identifierType === NodeIdType.STRING) {
|
|
558
|
+
nodeId = new NodeId(NodeIdType.STRING, uaVariable.nodeId.value as string + `[${iAsText}]`, uaVariable.nodeId.namespace);
|
|
559
|
+
}
|
|
560
|
+
return { browseName, nodeId };
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
export function _bindExtensionObjectArray(
|
|
564
|
+
uaVariable: UAVariableImpl,
|
|
565
|
+
optionalExtensionObjectArray?: ExtensionObject[],
|
|
566
|
+
options?: BindExtensionObjectOptions
|
|
567
|
+
): ExtensionObject[] {
|
|
568
|
+
return _bindExtensionObjectMatrix(uaVariable, optionalExtensionObjectArray, options);
|
|
569
|
+
}
|
|
570
|
+
export function _bindExtensionObjectMatrix(
|
|
571
|
+
uaVariable: UAVariableImpl,
|
|
572
|
+
optionalExtensionObjectArray?: ExtensionObject[],
|
|
573
|
+
options?: BindExtensionObjectOptions
|
|
574
|
+
): ExtensionObject[] {
|
|
575
|
+
|
|
576
|
+
if (uaVariable.valueRank < 1) {
|
|
577
|
+
throw new Error("Variable must be a MultiDimensional array");
|
|
578
|
+
}
|
|
579
|
+
const arrayDimensions = uaVariable.arrayDimensions || [];
|
|
580
|
+
|
|
581
|
+
if (!isVariableContainingExtensionObject(uaVariable)) {
|
|
582
|
+
return [];
|
|
583
|
+
}
|
|
584
|
+
if ((arrayDimensions.length === 0 || arrayDimensions.length === 1 && arrayDimensions[0] === 0) && optionalExtensionObjectArray) {
|
|
585
|
+
arrayDimensions[0] = optionalExtensionObjectArray.length;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
const totalLength = arrayDimensions.reduce((p, c) => p * c, 1);
|
|
589
|
+
|
|
590
|
+
/** */
|
|
591
|
+
const addressSpace = uaVariable.addressSpace;
|
|
592
|
+
if (optionalExtensionObjectArray) {
|
|
593
|
+
if (optionalExtensionObjectArray.length !== totalLength) {
|
|
594
|
+
throw new Error(`optionalExtensionObjectArray must have the expected number of element matching ${arrayDimensions}`)
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
if (!optionalExtensionObjectArray) {
|
|
598
|
+
optionalExtensionObjectArray = [];
|
|
599
|
+
for (let i = 0; i < totalLength; i++) {
|
|
600
|
+
optionalExtensionObjectArray[i] = addressSpace.constructExtensionObject(uaVariable.dataType, {});;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
uaVariable.$$extensionObjectArray = optionalExtensionObjectArray;
|
|
604
|
+
|
|
605
|
+
// uaVariable.$$getElementBrowseName = getElementBrowseNameByIndex;
|
|
606
|
+
|
|
607
|
+
uaVariable.bindVariable({
|
|
608
|
+
get: () => new Variant({
|
|
609
|
+
arrayType: VariantArrayType.Array,
|
|
610
|
+
dataType: DataType.ExtensionObject,
|
|
611
|
+
value: uaVariable.$$extensionObjectArray
|
|
612
|
+
})
|
|
613
|
+
}, true);
|
|
614
|
+
const namespace = uaVariable.namespace;
|
|
615
|
+
const indexIterator = new IndexIterator(arrayDimensions);
|
|
616
|
+
for (let i = 0; i < totalLength; i++) {
|
|
617
|
+
|
|
618
|
+
const index = indexIterator.next();
|
|
619
|
+
|
|
620
|
+
const { browseName, nodeId } = composeBrowseNameAndNodeId(uaVariable, index);
|
|
621
|
+
|
|
622
|
+
const uaElement = namespace.addVariable({
|
|
623
|
+
browseName,
|
|
624
|
+
nodeId,
|
|
625
|
+
componentOf: uaVariable,
|
|
626
|
+
dataType: uaVariable.dataType,
|
|
627
|
+
valueRank: -1,
|
|
628
|
+
accessLevel: uaVariable.userAccessLevel
|
|
629
|
+
});
|
|
630
|
+
{
|
|
631
|
+
const capturedIndex = i;
|
|
632
|
+
uaElement.bindVariable({
|
|
633
|
+
get: () => new Variant({
|
|
634
|
+
dataType: DataType.ExtensionObject,
|
|
635
|
+
arrayType: VariantArrayType.Scalar,
|
|
636
|
+
value: uaVariable.$$extensionObjectArray[capturedIndex]
|
|
637
|
+
})
|
|
638
|
+
})
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return uaVariable.$$extensionObjectArray;
|
|
642
|
+
}
|
|
643
|
+
|
|
491
644
|
export function extractPartialData(path: string | string[], extensionObject: ExtensionObject) {
|
|
492
645
|
let name;
|
|
493
646
|
if (typeof path === "string") {
|