node-opcua-address-space 2.66.1 → 2.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/source/address_space_ts.d.ts +0 -2
  2. package/dist/source/address_space_ts.js.map +1 -1
  3. package/dist/source/continuation_points/continuation_point_manager.js +3 -0
  4. package/dist/source/continuation_points/continuation_point_manager.js.map +1 -1
  5. package/dist/source/loader/make_xml_extension_object_parser.js +28 -9
  6. package/dist/source/loader/make_xml_extension_object_parser.js.map +1 -1
  7. package/dist/src/base_node_impl.js +1 -1
  8. package/dist/src/base_node_impl.js.map +1 -1
  9. package/dist/src/extension_object_array_node.js +31 -22
  10. package/dist/src/extension_object_array_node.js.map +1 -1
  11. package/dist/src/reference_impl.js +1 -1
  12. package/dist/src/reference_impl.js.map +1 -1
  13. package/dist/src/ua_variable_impl.d.ts +9 -8
  14. package/dist/src/ua_variable_impl.js +54 -311
  15. package/dist/src/ua_variable_impl.js.map +1 -1
  16. package/dist/src/ua_variable_impl_ext_obj.d.ts +17 -0
  17. package/dist/src/ua_variable_impl_ext_obj.js +393 -0
  18. package/dist/src/ua_variable_impl_ext_obj.js.map +1 -0
  19. package/package.json +36 -36
  20. package/source/address_space_ts.ts +0 -2
  21. package/source/continuation_points/continuation_point_manager.ts +8 -6
  22. package/source/loader/make_xml_extension_object_parser.ts +32 -11
  23. package/src/base_node_impl.ts +1 -1
  24. package/src/extension_object_array_node.ts +43 -28
  25. package/src/reference_impl.ts +1 -1
  26. package/src/ua_variable_impl.ts +66 -379
  27. package/src/ua_variable_impl_ext_obj.ts +472 -0
  28. package/test_helpers/test_fixtures/issue_1132_variable_with_nodeid_value.xml +68 -0
@@ -1,4 +1,4 @@
1
- import { CloneExtraInfo, ContinuationData, VariableDataValueSetterWithCallback } from "node-opcua-address-space-base";
1
+ import { BindExtensionObjectOptions, CloneExtraInfo, ContinuationData, VariableDataValueSetterWithCallback } from "node-opcua-address-space-base";
2
2
  import { QualifiedNameLike, NodeClass, AccessLevelFlag, AttributeIds } from "node-opcua-data-model";
3
3
  import { DataValue, DataValueT } from "node-opcua-data-value";
4
4
  import { PreciseClock } from "node-opcua-date-time";
@@ -148,13 +148,8 @@ export declare class UAVariableImpl extends BaseNodeImpl implements UAVariable {
148
148
  */
149
149
  checkVariantCompatibility(value: Variant): StatusCode;
150
150
  /**
151
- * @method touchValue
152
151
  * touch the source timestamp of a Variable and cascade up the change
153
152
  * to the parent variable if any.
154
- *
155
- * @param [optionalNow=null] {Object}
156
- * @param optionalNow.timestamp {Date}
157
- * @param optionalNow.picoseconds {Number}
158
153
  */
159
154
  touchValue(optionalNow?: PreciseClock): void;
160
155
  /**
@@ -290,16 +285,22 @@ export declare class UAVariableImpl extends BaseNodeImpl implements UAVariable {
290
285
  getDataTypeNode(): UADataType;
291
286
  get dataTypeObj(): UADataType;
292
287
  checkExtensionObjectIsCorrect(extObj: ExtensionObject | ExtensionObject[] | null): boolean;
288
+ /**
289
+ * @private
290
+ * install UAVariable to exposed th
291
+ *
292
+ * precondition:
293
+ */
294
+ installExtensionObjectVariables(): void;
293
295
  /**
294
296
  * @method bindExtensionObject
295
297
  * @return {ExtensionObject}
296
298
  */
297
- bindExtensionObject(optionalExtensionObject?: ExtensionObject): ExtensionObject | null;
299
+ bindExtensionObject(optionalExtensionObject?: ExtensionObject, options?: BindExtensionObjectOptions): ExtensionObject | null;
298
300
  updateExtensionObjectPartial(partialExtensionObject?: {
299
301
  [key: string]: any;
300
302
  }): ExtensionObject;
301
303
  incrementExtensionObjectPartial(path: string | string[]): void;
302
- constructExtensionObjectFromComponents(): any;
303
304
  toString(): string;
304
305
  historyRead(context: ISessionContext, historyReadDetails: HistoryReadDetails | ReadRawModifiedDetails | ReadEventDetails | ReadProcessedDetails | ReadAtTimeDetails, indexRange: NumericRange | null, dataEncoding: QualifiedNameLike | null, continuationData: ContinuationData): Promise<HistoryReadResult>;
305
306
  historyRead(context: ISessionContext, historyReadDetails: HistoryReadDetails | ReadRawModifiedDetails | ReadEventDetails | ReadProcessedDetails | ReadAtTimeDetails, indexRange: NumericRange | null, dataEncoding: QualifiedNameLike | null, continuationData: ContinuationData, callback: CallbackT<HistoryReadResult>): void;
@@ -22,7 +22,6 @@ const node_opcua_service_write_1 = require("node-opcua-service-write");
22
22
  const node_opcua_status_code_1 = require("node-opcua-status-code");
23
23
  const node_opcua_types_1 = require("node-opcua-types");
24
24
  const utils = require("node-opcua-utils");
25
- const node_opcua_utils_1 = require("node-opcua-utils");
26
25
  const node_opcua_variant_1 = require("node-opcua-variant");
27
26
  const session_context_1 = require("../source/session_context");
28
27
  const multiform_func_1 = require("../source/helpers/multiform_func");
@@ -30,6 +29,7 @@ const base_node_impl_1 = require("./base_node_impl");
30
29
  const base_node_private_1 = require("./base_node_private");
31
30
  const ua_data_type_impl_1 = require("./ua_data_type_impl");
32
31
  const apply_condition_refresh_1 = require("./apply_condition_refresh");
32
+ const ua_variable_impl_ext_obj_1 = require("./ua_variable_impl_ext_obj");
33
33
  const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
34
34
  const warningLog = (0, node_opcua_debug_1.make_warningLog)(__filename);
35
35
  const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
@@ -478,7 +478,8 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
478
478
  }
479
479
  if (this.dataType.namespace === 0 &&
480
480
  this.dataType.value === node_opcua_variant_1.DataType.LocalizedText &&
481
- variant.dataType !== node_opcua_variant_1.DataType.LocalizedText && variant.dataType !== node_opcua_variant_1.DataType.Null) {
481
+ variant.dataType !== node_opcua_variant_1.DataType.LocalizedText &&
482
+ variant.dataType !== node_opcua_variant_1.DataType.Null) {
482
483
  throw new Error("Variant must provide a valid LocalizedText : variant = " +
483
484
  variant.toString() +
484
485
  " this.dataType= " +
@@ -547,7 +548,21 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
547
548
  dataValue.sourceTimestamp = now.timestamp;
548
549
  dataValue.statusCode = statusCode;
549
550
  dataValue.value = variant1;
550
- this._internal_set_dataValue(dataValue);
551
+ if (dataValue.value.dataType === node_opcua_variant_1.DataType.ExtensionObject) {
552
+ this.$dataValue = dataValue;
553
+ (0, node_opcua_assert_1.assert)(this.checkExtensionObjectIsCorrect(dataValue.value.value));
554
+ // ----------------------------------
555
+ if (this.$extensionObject) {
556
+ // we have an extension object already bound to this node
557
+ // the client is asking us to replace the object entierly by a new one
558
+ const ext = dataValue.value.value;
559
+ (0, ua_variable_impl_ext_obj_1._setExtensionObject)(this, ext);
560
+ return;
561
+ }
562
+ }
563
+ else {
564
+ this._internal_set_dataValue(dataValue);
565
+ }
551
566
  }
552
567
  catch (err) {
553
568
  errorLog("UAVariable#setValueFromString Error : ", this.browseName.toString(), this.nodeId.toString());
@@ -730,30 +745,12 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
730
745
  return node_opcua_status_code_1.StatusCodes.Good;
731
746
  }
732
747
  /**
733
- * @method touchValue
734
748
  * touch the source timestamp of a Variable and cascade up the change
735
749
  * to the parent variable if any.
736
- *
737
- * @param [optionalNow=null] {Object}
738
- * @param optionalNow.timestamp {Date}
739
- * @param optionalNow.picoseconds {Number}
740
750
  */
741
751
  touchValue(optionalNow) {
742
752
  const now = optionalNow || (0, node_opcua_date_time_1.getCurrentClock)();
743
- this.$dataValue.sourceTimestamp = now.timestamp;
744
- this.$dataValue.sourcePicoseconds = now.picoseconds;
745
- this.$dataValue.serverTimestamp = now.timestamp;
746
- this.$dataValue.serverPicoseconds = now.picoseconds;
747
- this.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
748
- if (this.minimumSamplingInterval === 0) {
749
- if (this.listenerCount("value_changed") > 0) {
750
- const clonedDataValue = this.readValue();
751
- this.emit("value_changed", clonedDataValue);
752
- }
753
- }
754
- if (this.parent && this.parent.nodeClass === node_opcua_data_model_1.NodeClass.Variable) {
755
- this.parent.touchValue(now);
756
- }
753
+ (0, ua_variable_impl_ext_obj_1.propagateTouchValueUpward)(this, now);
757
754
  }
758
755
  /**
759
756
  * bind a variable with a get and set functions.
@@ -972,6 +969,11 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
972
969
  (0, node_opcua_assert_1.assert)(typeof newVariable._timestamped_set_func === "function");
973
970
  (0, node_opcua_assert_1.assert)(newVariable.dataType === this.dataType);
974
971
  newVariable.$dataValue = this.$dataValue.clone();
972
+ // also bind extension object
973
+ const v = newVariable.$dataValue.value;
974
+ if (v.dataType === node_opcua_variant_1.DataType.ExtensionObject && v.value && v.arrayType === node_opcua_variant_1.VariantArrayType.Scalar) {
975
+ newVariable.bindExtensionObject(newVariable.$dataValue.value.value);
976
+ }
975
977
  return newVariable;
976
978
  }
977
979
  getDataTypeNode() {
@@ -1026,262 +1028,37 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
1026
1028
  }
1027
1029
  }
1028
1030
  /**
1029
- * @method bindExtensionObject
1030
- * @return {ExtensionObject}
1031
+ * @private
1032
+ * install UAVariable to exposed th
1033
+ *
1034
+ * precondition:
1031
1035
  */
1032
- bindExtensionObject(optionalExtensionObject) {
1033
- var _a, _b;
1034
- const addressSpace = this.addressSpace;
1035
- const structure = addressSpace.findDataType("Structure");
1036
- let extensionObject_;
1037
- if (!structure) {
1038
- // the addressSpace is limited and doesn't provide extension object
1039
- // bindExtensionObject cannot be performed and shall finish here.
1040
- return null;
1041
- }
1042
- // istanbul ignore next
1043
- if (doDebug) {
1044
- debugLog(" ------------------------------ binding ", this.browseName.toString(), this.nodeId.toString());
1045
- }
1046
- (0, node_opcua_assert_1.assert)(structure && structure.browseName.toString() === "Structure", "expecting DataType Structure to be in IAddressSpace");
1047
- const dt = this.getDataTypeNode();
1048
- if (!dt.isSupertypeOf(structure)) {
1049
- return null;
1050
- }
1051
- // the namespace for the structure browse name elements
1052
- const structureNamespace = dt.nodeId.namespace;
1053
- // -------------------- make sure we do not bind a variable twice ....
1054
- if (this.$extensionObject) {
1055
- // istanbul ignore next
1056
- // if (!force && !utils.isNullOrUndefined(optionalExtensionObject)) {
1057
- // throw new Error(
1058
- // "bindExtensionObject: unsupported case : $extensionObject already exists on " +
1059
- // this.browseName.toString() +
1060
- // " " +
1061
- // this.nodeId.toString()
1062
- // );
1063
- // }
1064
- // istanbul ignore next
1065
- if (!this.checkExtensionObjectIsCorrect(this.$extensionObject)) {
1066
- warningLog("on node : ", this.browseName.toString(), this.nodeId.toString(), "dataType=", this.dataType.toString({ addressSpace: this.addressSpace }));
1067
- warningLog((_a = this.$extensionObject) === null || _a === void 0 ? void 0 : _a.toString());
1068
- throw new Error("bindExtensionObject: $extensionObject is incorrect: we are expecting a " +
1069
- this.dataType.toString({ addressSpace: this.addressSpace }) +
1070
- " but we got a " +
1071
- ((_b = this.$extensionObject) === null || _b === void 0 ? void 0 : _b.constructor.name));
1072
- }
1073
- return this.$extensionObject;
1074
- // throw new Error("Variable already bound");
1075
- }
1076
- this.$extensionObject = optionalExtensionObject;
1077
- // ------------------------------------------------------------------
1078
- function prepareVariantValue(dataType, value) {
1079
- if ((dataType === node_opcua_variant_1.DataType.Int32 || dataType === node_opcua_variant_1.DataType.UInt32) && value && value.key) {
1080
- value = value.value;
1081
- }
1082
- return value;
1083
- }
1084
- const bindProperty = (propertyNode, name, extensionObject, dataType) => {
1085
- // eslint-disable-next-line @typescript-eslint/no-this-alias
1086
- const self = this;
1087
- propertyNode.bindVariable({
1088
- timestamped_get: () => {
1089
- const propertyValue = self.$extensionObject[name];
1090
- if (propertyValue === undefined) {
1091
- propertyNode.$dataValue.value.dataType = node_opcua_variant_1.DataType.Null;
1092
- propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
1093
- propertyNode.$dataValue.value.value = null;
1094
- return new node_opcua_data_value_1.DataValue(propertyNode.$dataValue);
1095
- }
1096
- const value = prepareVariantValue(dataType, propertyValue);
1097
- propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
1098
- propertyNode.$dataValue.value.dataType = dataType;
1099
- propertyNode.$dataValue.value.value = value;
1100
- return new node_opcua_data_value_1.DataValue(propertyNode.$dataValue);
1101
- },
1102
- timestamped_set: (dataValue, callback) => {
1103
- dataValue;
1104
- callback(null, node_opcua_status_code_1.StatusCodes.BadNotWritable);
1036
+ installExtensionObjectVariables() {
1037
+ (0, ua_variable_impl_ext_obj_1._installExtensionObjectBindingOnProperties)(this, { createMissingProp: true });
1038
+ // now recursively install extension object on children
1039
+ for (const child of this.getComponents()) {
1040
+ if (child.nodeClass === node_opcua_data_model_1.NodeClass.Variable && child instanceof UAVariableImpl) {
1041
+ if (child.isExtensionObject()) {
1042
+ child.installExtensionObjectVariables();
1105
1043
  }
1106
- }, true);
1107
- };
1108
- const components = this.getComponents();
1109
- // ------------------------------------------------------
1110
- // make sure we have a structure
1111
- // ------------------------------------------------------
1112
- const s = this.readValue();
1113
- // istanbul ignore next
1114
- if (this.dataTypeObj.isAbstract) {
1115
- warningLog("Warning the DataType associated with this Variable is abstract ", this.dataTypeObj.browseName.toString());
1116
- warningLog("You need to provide a extension object yourself ");
1117
- throw new Error("bindExtensionObject requires a extensionObject as associated dataType is only abstract");
1118
- }
1119
- if (s.value && (s.value.dataType === node_opcua_variant_1.DataType.Null || (s.value.dataType === node_opcua_variant_1.DataType.ExtensionObject && !s.value.value))) {
1120
- // create a structure and bind it
1121
- extensionObject_ = this.$extensionObject || addressSpace.constructExtensionObject(this.dataType, {});
1122
- extensionObject_ = new Proxy(extensionObject_, makeHandler(this));
1123
- this.$extensionObject = extensionObject_;
1124
- const theValue = new node_opcua_variant_1.Variant({
1125
- dataType: node_opcua_variant_1.DataType.ExtensionObject,
1126
- value: this.$extensionObject
1127
- });
1128
- this.setValueFromSource(theValue, node_opcua_status_code_1.StatusCodes.Good);
1129
- // eslint-disable-next-line @typescript-eslint/no-this-alias
1130
- const self = this;
1131
- this.bindVariable({
1132
- timestamped_get() {
1133
- self.$dataValue.value.value = self.$extensionObject;
1134
- const d = new node_opcua_data_value_1.DataValue(self.$dataValue);
1135
- d.value = new node_opcua_variant_1.Variant(d.value);
1136
- return d;
1137
- },
1138
- timestamped_set(dataValue, callback) {
1139
- const ext = dataValue.value.value;
1140
- if (!self.checkExtensionObjectIsCorrect(ext)) {
1141
- return callback(null, node_opcua_status_code_1.StatusCodes.BadInvalidArgument);
1142
- }
1143
- self.$extensionObject = new Proxy(ext, makeHandler(self));
1144
- self.touchValue();
1145
- callback(null, node_opcua_status_code_1.StatusCodes.Good);
1146
- }
1147
- }, true);
1148
- }
1149
- else {
1150
- // verify that variant has the correct type
1151
- (0, node_opcua_assert_1.assert)(s.value.dataType === node_opcua_variant_1.DataType.ExtensionObject);
1152
- this.$extensionObject = s.value.value;
1153
- (0, node_opcua_assert_1.assert)(this.checkExtensionObjectIsCorrect(this.$extensionObject));
1154
- (0, node_opcua_assert_1.assert)(s.statusCode.equals(node_opcua_status_code_1.StatusCodes.Good));
1155
- }
1156
- // ------------------------------------------------------
1157
- // now bind each member
1158
- // ------------------------------------------------------
1159
- const definition = dt._getDefinition();
1160
- // istanbul ignore next
1161
- if (!definition) {
1162
- throw new Error("xx definition missing in " + dt.toString());
1163
- }
1164
- const getOrCreateProperty = (field) => {
1165
- let property;
1166
- const selectedComponents = components.filter((f) => f instanceof UAVariableImpl && f.browseName.name.toString() === field.name);
1167
- if (field.dataType.value === node_opcua_variant_1.DataType.Variant) {
1168
- warningLog("Warning : variant is not supported in ExtensionObject");
1169
- }
1170
- if (selectedComponents.length === 1) {
1171
- property = selectedComponents[0];
1172
- /* istanbul ignore next */
1173
1044
  }
1174
- else {
1175
- debugLog("adding missing array variable", field.name, this.browseName.toString(), this.nodeId.toString());
1176
- // todo: Handle array appropriately...
1177
- (0, node_opcua_assert_1.assert)(selectedComponents.length === 0);
1178
- // create a variable (Note we may use ns=1;s=parentName/0:PropertyName)
1179
- property = this.namespace.addVariable({
1180
- browseName: { namespaceIndex: structureNamespace, name: field.name.toString() },
1181
- componentOf: this,
1182
- dataType: field.dataType,
1183
- minimumSamplingInterval: this.minimumSamplingInterval
1184
- });
1185
- (0, node_opcua_assert_1.assert)(property.minimumSamplingInterval === this.minimumSamplingInterval);
1186
- }
1187
- return property;
1188
- };
1189
- for (const field of definition.fields || []) {
1190
- if (node_opcua_nodeid_1.NodeId.sameNodeId(node_opcua_nodeid_1.NodeId.nullNodeId, field.dataType)) {
1191
- warningLog("field.dataType is null ! ", field.toString(), node_opcua_nodeid_1.NodeId.nullNodeId.toString());
1192
- warningLog(" dataType replaced with BaseDataType ");
1193
- warningLog(definition.toString());
1194
- field.dataType = this.resolveNodeId("BaseDataType");
1195
- }
1196
- const camelCaseName = (0, node_opcua_utils_1.lowerFirstLetter)(field.name);
1197
- (0, node_opcua_assert_1.assert)(Object.prototype.hasOwnProperty.call(this.$extensionObject, camelCaseName));
1198
- const propertyNode = getOrCreateProperty(field);
1199
- propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
1200
- propertyNode.touchValue();
1201
- const basicDataType = addressSpace.findCorrespondingBasicDataType(field.dataType);
1202
- // istanbul ignore next
1203
- if (doDebug) {
1204
- const x = addressSpace.findNode(field.dataType).browseName.toString();
1205
- debugLog(chalk.cyan("xxx"), " dataType", w(field.dataType.toString(), 8), w(field.name, 35), "valueRank", chalk.cyan(w((0, base_node_private_1.valueRankToString)(field.valueRank), 10)), chalk.green(w(x, 25)), "basicType = ", chalk.yellow(w(basicDataType.toString(), 20)), propertyNode.nodeId.toString(), propertyNode.readValue().statusCode.toString());
1206
- }
1207
- if (this.$extensionObject[camelCaseName] !== undefined && basicDataType === node_opcua_variant_1.DataType.ExtensionObject) {
1208
- (0, node_opcua_assert_1.assert)(this.$extensionObject[camelCaseName] instanceof Object);
1209
- this.$extensionObject[camelCaseName] = new Proxy(this.$extensionObject[camelCaseName], makeHandler(propertyNode));
1210
- propertyNode._internal_set_value(new node_opcua_variant_1.Variant({
1211
- dataType: node_opcua_variant_1.DataType.ExtensionObject,
1212
- value: this.$extensionObject[camelCaseName]
1213
- }));
1214
- propertyNode.bindExtensionObject();
1215
- propertyNode.$extensionObject = this.$extensionObject[camelCaseName];
1216
- }
1217
- else {
1218
- const prop = this.$extensionObject[camelCaseName];
1219
- if (prop === undefined) {
1220
- propertyNode._internal_set_value(new node_opcua_variant_1.Variant({
1221
- dataType: node_opcua_variant_1.DataType.Null
1222
- }));
1223
- }
1224
- else {
1225
- const preparedValue = prepareVariantValue(basicDataType, prop);
1226
- propertyNode._internal_set_value(new node_opcua_variant_1.Variant({
1227
- dataType: basicDataType,
1228
- value: preparedValue
1229
- }));
1230
- }
1231
- // eslint-disable-next-line @typescript-eslint/no-this-alias
1232
- const self = this;
1233
- // property.camelCaseName = camelCaseName;
1234
- propertyNode.setValueFromSource = function (variant) {
1235
- // eslint-disable-next-line @typescript-eslint/no-this-alias
1236
- const inner_this = this;
1237
- const variant1 = node_opcua_variant_1.Variant.coerce(variant);
1238
- inner_this.verifyVariantCompatibility(variant1);
1239
- self.$extensionObject[camelCaseName] = variant1.value;
1240
- self.touchValue();
1241
- };
1242
- }
1243
- (0, node_opcua_assert_1.assert)(propertyNode.readValue().statusCode.equals(node_opcua_status_code_1.StatusCodes.Good));
1244
- bindProperty(propertyNode, camelCaseName, this.$extensionObject, basicDataType);
1245
1045
  }
1246
- (0, node_opcua_assert_1.assert)(this.$extensionObject instanceof Object);
1247
- return this.$extensionObject;
1046
+ }
1047
+ /**
1048
+ * @method bindExtensionObject
1049
+ * @return {ExtensionObject}
1050
+ */
1051
+ bindExtensionObject(optionalExtensionObject, options) {
1052
+ return (0, ua_variable_impl_ext_obj_1._bindExtensionObject)(this, optionalExtensionObject, options);
1248
1053
  }
1249
1054
  updateExtensionObjectPartial(partialExtensionObject) {
1250
- setExtensionObjectValue(this, partialExtensionObject);
1055
+ (0, ua_variable_impl_ext_obj_1.setExtensionObjectValue)(this, partialExtensionObject);
1251
1056
  return this.$extensionObject;
1252
1057
  }
1253
1058
  incrementExtensionObjectPartial(path) {
1254
- let name;
1255
- if (typeof path === "string") {
1256
- path = path.split(".");
1257
- }
1258
- (0, node_opcua_assert_1.assert)(path instanceof Array);
1259
- const extensionObject = this.constructExtensionObjectFromComponents();
1260
- let i;
1261
- // read partial value
1262
- const partialData = {};
1263
- let p = partialData;
1264
- for (i = 0; i < path.length - 1; i++) {
1265
- name = path[i];
1266
- p[name] = {};
1267
- p = p[name];
1268
- }
1269
- name = path[path.length - 1];
1270
- p[name] = 0;
1271
- let c1 = partialData;
1272
- let c2 = extensionObject;
1273
- for (i = 0; i < path.length - 1; i++) {
1274
- name = path[i];
1275
- c1 = partialData[name];
1276
- c2 = extensionObject[name];
1277
- }
1278
- name = path[path.length - 1];
1279
- c1[name] = c2[name];
1280
- c1[name] += 1;
1281
- setExtensionObjectValue(this, partialData);
1282
- }
1283
- constructExtensionObjectFromComponents() {
1284
- return this.readValue().value.value;
1059
+ const extensionObject = this.readValue().value.value;
1060
+ const partialData = (0, ua_variable_impl_ext_obj_1.extractPartialData)(path, extensionObject);
1061
+ (0, ua_variable_impl_ext_obj_1.setExtensionObjectValue)(this, partialData);
1285
1062
  }
1286
1063
  toString() {
1287
1064
  const options = new base_node_private_1.ToStringBuilder();
@@ -1356,6 +1133,14 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
1356
1133
  warningLog(dataValue.toString());
1357
1134
  throw new Error("Invalid Extension Object on nodeId =" + this.nodeId.toString());
1358
1135
  }
1136
+ // ----------------------------------
1137
+ // if (this.$extensionObject) {
1138
+ // // we have an extension object already bound to this node
1139
+ // // the client is asking us to replace the object entierly by a new one
1140
+ // const ext = dataValue.value.value;
1141
+ // _setExtensionObject(this, ext);
1142
+ // return;
1143
+ // }
1359
1144
  }
1360
1145
  // // istanbul ignore next
1361
1146
  // if (this.dataType.namespace === 0) {
@@ -1750,48 +1535,6 @@ function bind_getter(options) {
1750
1535
  }
1751
1536
  }
1752
1537
  }
1753
- function w(str, n) {
1754
- return (str + " ").substr(0, n);
1755
- }
1756
- function _getter(target, key /*, receiver*/) {
1757
- if (target[key] === undefined) {
1758
- return undefined;
1759
- }
1760
- return target[key];
1761
- }
1762
- function _setter(variable, target, key, value /*, receiver*/) {
1763
- target[key] = value;
1764
- const child = variable[key];
1765
- if (child && child.touchValue) {
1766
- child.touchValue();
1767
- }
1768
- return true; // true means the set operation has succeeded
1769
- }
1770
- function makeHandler(variable) {
1771
- const handler = {
1772
- get: _getter,
1773
- set: _setter.bind(null, variable)
1774
- };
1775
- return handler;
1776
- }
1777
- function setExtensionObjectValue(node, partialObject) {
1778
- const extensionObject = node.$extensionObject;
1779
- if (!extensionObject) {
1780
- throw new Error("setExtensionObjectValue node has no extension object " + node.browseName.toString());
1781
- }
1782
- function _update_extension_object(extObject, partialObject1) {
1783
- const keys = Object.keys(partialObject1);
1784
- for (const prop of keys) {
1785
- if (extObject[prop] instanceof Object) {
1786
- _update_extension_object(extObject[prop], partialObject1[prop]);
1787
- }
1788
- else {
1789
- extObject[prop] = partialObject1[prop];
1790
- }
1791
- }
1792
- }
1793
- _update_extension_object(extensionObject, partialObject);
1794
- }
1795
1538
  class UAVariableImplT extends UAVariableImpl {
1796
1539
  }
1797
1540
  exports.UAVariableImplT = UAVariableImplT;