node-opcua-address-space 2.87.0 → 2.89.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/address_space_ts.d.ts +4 -4
- package/dist/source/address_space_ts.js +3 -3
- package/dist/source/address_space_ts.js.map +1 -1
- package/dist/source/helpers/argument_list.js +8 -12
- package/dist/source/helpers/argument_list.js.map +1 -1
- package/dist/source/helpers/call_helpers.d.ts +1 -1
- package/dist/source/helpers/multiform_func.d.ts +8 -8
- package/dist/source/interfaces/alarms_and_conditions/ua_condition_ex.d.ts +1 -1
- package/dist/source/interfaces/extension_object_constructor.d.ts +1 -1
- package/dist/source/interfaces/state_machine/ua_state_machine_type.d.ts +2 -2
- package/dist/source/loader/generateAddressSpaceRaw.d.ts +2 -2
- package/dist/source/loader/make_xml_extension_object_parser.d.ts +1 -1
- package/dist/source/loader/namespace_post_step.d.ts +1 -1
- package/dist/source/session_context.d.ts +1 -1
- package/dist/src/address_space.js +11 -11
- package/dist/src/address_space.js.map +1 -1
- package/dist/src/apply_condition_refresh.d.ts +1 -1
- package/dist/src/base_node_impl.js +44 -44
- package/dist/src/base_node_impl.js.map +1 -1
- package/dist/src/event_data.d.ts +2 -2
- package/dist/src/extension_object_array_node.d.ts +3 -41
- package/dist/src/extension_object_array_node.js +20 -54
- 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/nodeid_manager.d.ts +3 -3
- package/dist/src/nodeset_tools/nodeset_to_xml.d.ts +1 -1
- package/dist/src/reference_impl.js +6 -6
- package/dist/src/reference_impl.js.map +1 -1
- package/dist/src/tool_isSupertypeOf.d.ts +4 -4
- package/dist/src/ua_data_type_impl.js +12 -12
- package/dist/src/ua_data_type_impl.js.map +1 -1
- package/dist/src/ua_method_impl.js +6 -6
- package/dist/src/ua_method_impl.js.map +1 -1
- package/dist/src/ua_object_impl.js +7 -7
- package/dist/src/ua_object_impl.js.map +1 -1
- package/dist/src/ua_object_type_impl.js +6 -6
- package/dist/src/ua_object_type_impl.js.map +1 -1
- package/dist/src/ua_reference_type_impl.d.ts +1 -1
- package/dist/src/ua_reference_type_impl.js +6 -6
- package/dist/src/ua_reference_type_impl.js.map +1 -1
- package/dist/src/ua_variable_impl.d.ts +15 -9
- package/dist/src/ua_variable_impl.js +57 -50
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/dist/src/ua_variable_impl_ext_obj.d.ts +10 -6
- package/dist/src/ua_variable_impl_ext_obj.js +368 -189
- package/dist/src/ua_variable_impl_ext_obj.js.map +1 -1
- package/dist/src/ua_variable_type_impl.js +7 -7
- package/dist/src/ua_variable_type_impl.js.map +1 -1
- package/dist/src/ua_view_impl.js +3 -3
- package/dist/src/ua_view_impl.js.map +1 -1
- package/package.json +40 -40
- package/source/address_space_ts.ts +1 -1
- package/source/helpers/argument_list.ts +26 -26
- package/src/extension_object_array_node.ts +25 -63
- package/src/idx_iterator.ts +52 -0
- package/src/ua_variable_impl.ts +65 -55
- package/src/ua_variable_impl_ext_obj.ts +429 -231
- package/src/ua_variable_type_impl.ts +4 -4
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.extractPartialData = exports.
|
|
4
|
-
const chalk = require("chalk");
|
|
3
|
+
exports.extractPartialData = exports.incrementElement = exports.setElement = exports.getElement = exports._bindExtensionObjectArrayOrMatrix = exports._bindExtensionObject = exports._installExtensionObjectBindingOnProperties = exports.setExtensionObjectPartialValue = exports.propagateTouchValueUpward = exports._touchValue = exports.getProxyTarget = void 0;
|
|
5
4
|
const node_opcua_assert_1 = require("node-opcua-assert");
|
|
6
5
|
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
7
6
|
const node_opcua_date_time_1 = require("node-opcua-date-time");
|
|
8
|
-
const node_opcua_data_value_1 = require("node-opcua-data-value");
|
|
9
7
|
const node_opcua_debug_1 = require("node-opcua-debug");
|
|
8
|
+
const node_opcua_extension_object_1 = require("node-opcua-extension-object");
|
|
10
9
|
const node_opcua_nodeid_1 = require("node-opcua-nodeid");
|
|
11
10
|
const node_opcua_status_code_1 = require("node-opcua-status-code");
|
|
12
11
|
const node_opcua_utils_1 = require("node-opcua-utils");
|
|
13
12
|
const node_opcua_variant_1 = require("node-opcua-variant");
|
|
14
|
-
const base_node_private_1 = require("./base_node_private");
|
|
15
13
|
const ua_variable_impl_1 = require("./ua_variable_impl");
|
|
14
|
+
const idx_iterator_1 = require("./idx_iterator");
|
|
16
15
|
const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
|
|
17
16
|
const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
|
|
18
17
|
// const doDebug = true; // checkDebugFlag(__filename);
|
|
@@ -25,37 +24,61 @@ function w(str, n) {
|
|
|
25
24
|
function isProxy(ext) {
|
|
26
25
|
return ext.$isProxy ? true : false;
|
|
27
26
|
}
|
|
27
|
+
function getProxyVariable(ext) {
|
|
28
|
+
(0, node_opcua_assert_1.default)(isProxy(ext));
|
|
29
|
+
return ext.$variable;
|
|
30
|
+
}
|
|
31
|
+
function getProxyVariableForProp(ext, prop) {
|
|
32
|
+
const uaVariable = getProxyVariable(ext);
|
|
33
|
+
if (!uaVariable)
|
|
34
|
+
return undefined;
|
|
35
|
+
return uaVariable[prop];
|
|
36
|
+
}
|
|
28
37
|
function getProxyTarget(ext) {
|
|
29
38
|
(0, node_opcua_assert_1.default)(isProxy(ext));
|
|
30
|
-
|
|
39
|
+
const target = ext.$proxyTarget;
|
|
40
|
+
if (target && isProxy(target)) {
|
|
41
|
+
return getProxyTarget(target);
|
|
42
|
+
}
|
|
43
|
+
return target;
|
|
31
44
|
}
|
|
45
|
+
exports.getProxyTarget = getProxyTarget;
|
|
32
46
|
function unProxy(ext) {
|
|
33
47
|
return isProxy(ext) ? getProxyTarget(ext) : ext;
|
|
34
48
|
}
|
|
35
|
-
function _extensionObjectFieldGetter(target, key /*, receiver*/) {
|
|
49
|
+
function _extensionObjectFieldGetter(getVariable, target, key /*, receiver*/) {
|
|
36
50
|
if (key === "$isProxy") {
|
|
37
51
|
return true;
|
|
38
52
|
}
|
|
39
53
|
if (key === "$proxyTarget") {
|
|
40
54
|
return target;
|
|
41
55
|
}
|
|
56
|
+
if (key === "$variable") {
|
|
57
|
+
return getVariable();
|
|
58
|
+
}
|
|
42
59
|
if (target[key] === undefined) {
|
|
43
60
|
return undefined;
|
|
44
61
|
}
|
|
45
62
|
return target[key];
|
|
46
63
|
}
|
|
47
|
-
function _extensionObjectFieldSetter(
|
|
64
|
+
function _extensionObjectFieldSetter(getVariable, target, key, value /*, receiver*/) {
|
|
48
65
|
target[key] = value;
|
|
49
|
-
|
|
66
|
+
if (isProxy(target)) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
const uaVariable = getVariable();
|
|
70
|
+
if (!uaVariable)
|
|
71
|
+
return true;
|
|
72
|
+
const child = uaVariable[key];
|
|
50
73
|
if (child && child.touchValue) {
|
|
51
74
|
child.touchValue();
|
|
52
75
|
}
|
|
53
76
|
return true; // true means the set operation has succeeded
|
|
54
77
|
}
|
|
55
|
-
function makeHandler(
|
|
78
|
+
function makeHandler(getVariable) {
|
|
56
79
|
const handler = {
|
|
57
|
-
get: _extensionObjectFieldGetter,
|
|
58
|
-
set: _extensionObjectFieldSetter.bind(null,
|
|
80
|
+
get: _extensionObjectFieldGetter.bind(null, getVariable),
|
|
81
|
+
set: _extensionObjectFieldSetter.bind(null, getVariable)
|
|
59
82
|
};
|
|
60
83
|
return handler;
|
|
61
84
|
}
|
|
@@ -79,17 +102,22 @@ function _touchValue(property, now) {
|
|
|
79
102
|
}
|
|
80
103
|
}
|
|
81
104
|
exports._touchValue = _touchValue;
|
|
82
|
-
function propagateTouchValueUpward(self, now) {
|
|
105
|
+
function propagateTouchValueUpward(self, now, cache) {
|
|
83
106
|
_touchValue(self, now);
|
|
84
107
|
if (self.parent && self.parent.nodeClass === node_opcua_data_model_1.NodeClass.Variable) {
|
|
85
108
|
const parentVar = self.parent;
|
|
86
109
|
if (!parentVar.isExtensionObject())
|
|
87
110
|
return;
|
|
88
|
-
|
|
111
|
+
if (cache) {
|
|
112
|
+
if (cache.has(parentVar))
|
|
113
|
+
return;
|
|
114
|
+
cache.add(parentVar);
|
|
115
|
+
}
|
|
116
|
+
propagateTouchValueUpward(parentVar, now, cache);
|
|
89
117
|
}
|
|
90
118
|
}
|
|
91
119
|
exports.propagateTouchValueUpward = propagateTouchValueUpward;
|
|
92
|
-
function propagateTouchValueDownward(self, now) {
|
|
120
|
+
function propagateTouchValueDownward(self, now, cache) {
|
|
93
121
|
if (!self.isExtensionObject())
|
|
94
122
|
return;
|
|
95
123
|
// also propagate changes to embeded variables
|
|
@@ -98,36 +126,19 @@ function propagateTouchValueDownward(self, now) {
|
|
|
98
126
|
for (const field of definition.fields || []) {
|
|
99
127
|
const property = self.getChildByName(field.name);
|
|
100
128
|
if (property) {
|
|
129
|
+
if (cache) {
|
|
130
|
+
if (cache.has(property)) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
cache.add(property);
|
|
134
|
+
}
|
|
101
135
|
_touchValue(property, now);
|
|
102
136
|
// to do cascade recursivelly ?
|
|
103
137
|
}
|
|
104
138
|
}
|
|
105
139
|
}
|
|
106
|
-
function
|
|
107
|
-
|
|
108
|
-
if (Array.isArray(ext)) {
|
|
109
|
-
(0, node_opcua_assert_1.default)(self.valueRank === 1, "Only Array is supported for the time being");
|
|
110
|
-
ext = ext.map((e) => unProxy(e));
|
|
111
|
-
self.$dataValue.value.arrayType = node_opcua_variant_1.VariantArrayType.Array;
|
|
112
|
-
self.$extensionObject = ext.map((e) => new Proxy(e, makeHandler(self)));
|
|
113
|
-
self.$dataValue.value.dataType = node_opcua_variant_1.DataType.ExtensionObject;
|
|
114
|
-
self.$dataValue.value.value = self.$extensionObject;
|
|
115
|
-
self.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
ext = unProxy(ext);
|
|
120
|
-
self.$extensionObject = new Proxy(ext, makeHandler(self));
|
|
121
|
-
self.$dataValue.value.dataType = node_opcua_variant_1.DataType.ExtensionObject;
|
|
122
|
-
self.$dataValue.value.value = self.$extensionObject;
|
|
123
|
-
self.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
124
|
-
}
|
|
125
|
-
const now = (0, node_opcua_date_time_1.getCurrentClock)();
|
|
126
|
-
propagateTouchValueUpward(self, now);
|
|
127
|
-
propagateTouchValueDownward(self, now);
|
|
128
|
-
}
|
|
129
|
-
exports._setExtensionObject = _setExtensionObject;
|
|
130
|
-
function setExtensionObjectValue(node, partialObject) {
|
|
140
|
+
function setExtensionObjectPartialValue(node, partialObject, sourceTimestamp) {
|
|
141
|
+
const variablesToUpdate = new Set();
|
|
131
142
|
const extensionObject = node.$extensionObject;
|
|
132
143
|
if (!extensionObject) {
|
|
133
144
|
throw new Error("setExtensionObjectValue node has no extension object " + node.browseName.toString());
|
|
@@ -139,13 +150,32 @@ function setExtensionObjectValue(node, partialObject) {
|
|
|
139
150
|
_update_extension_object(extObject[prop], partialObject1[prop]);
|
|
140
151
|
}
|
|
141
152
|
else {
|
|
142
|
-
extObject
|
|
153
|
+
if (isProxy(extObject)) {
|
|
154
|
+
// collect element we have to update
|
|
155
|
+
const target = getProxyTarget(extObject);
|
|
156
|
+
(0, node_opcua_assert_1.default)(!isProxy(target), "something wierd!");
|
|
157
|
+
target[prop] = partialObject1[prop];
|
|
158
|
+
const variable = getProxyVariableForProp(extObject, prop);
|
|
159
|
+
variable && variablesToUpdate.add(variable);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
extObject[prop] = partialObject1[prop];
|
|
163
|
+
}
|
|
143
164
|
}
|
|
144
165
|
}
|
|
145
166
|
}
|
|
146
167
|
_update_extension_object(extensionObject, partialObject);
|
|
168
|
+
const now = sourceTimestamp || (0, node_opcua_date_time_1.getCurrentClock)();
|
|
169
|
+
const cache = new Set();
|
|
170
|
+
for (const c of variablesToUpdate) {
|
|
171
|
+
if (cache.has(c))
|
|
172
|
+
continue;
|
|
173
|
+
propagateTouchValueUpward(c, now, cache);
|
|
174
|
+
propagateTouchValueDownward(c, now, cache);
|
|
175
|
+
cache.add(c);
|
|
176
|
+
}
|
|
147
177
|
}
|
|
148
|
-
exports.
|
|
178
|
+
exports.setExtensionObjectPartialValue = setExtensionObjectPartialValue;
|
|
149
179
|
function getOrCreateProperty(variableNode, field, options) {
|
|
150
180
|
const dt = variableNode.getDataTypeNode();
|
|
151
181
|
// the namespace for the structure browse name elements
|
|
@@ -173,7 +203,10 @@ function getOrCreateProperty(variableNode, field, options) {
|
|
|
173
203
|
browseName: { namespaceIndex: structureNamespace, name: field.name.toString() },
|
|
174
204
|
componentOf: variableNode,
|
|
175
205
|
dataType: field.dataType,
|
|
176
|
-
minimumSamplingInterval: variableNode.minimumSamplingInterval
|
|
206
|
+
minimumSamplingInterval: variableNode.minimumSamplingInterval,
|
|
207
|
+
accessLevel: variableNode.accessLevel,
|
|
208
|
+
accessRestrictions: variableNode.accessRestrictions,
|
|
209
|
+
rolePermissions: variableNode.rolePermissions
|
|
177
210
|
});
|
|
178
211
|
(0, node_opcua_assert_1.default)(property.minimumSamplingInterval === variableNode.minimumSamplingInterval);
|
|
179
212
|
}
|
|
@@ -185,121 +218,184 @@ function prepareVariantValue(dataType, value) {
|
|
|
185
218
|
}
|
|
186
219
|
return value;
|
|
187
220
|
}
|
|
188
|
-
function
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
221
|
+
function installExt(uaVariable, ext) {
|
|
222
|
+
ext = unProxy(ext);
|
|
223
|
+
uaVariable.$extensionObject = new Proxy(ext, makeHandler(() => uaVariable));
|
|
224
|
+
const addressSpace = uaVariable.addressSpace;
|
|
225
|
+
const definition = uaVariable.dataTypeObj.getStructureDefinition();
|
|
226
|
+
const structure = addressSpace.findDataType("Structure");
|
|
227
|
+
for (const field of definition.fields || []) {
|
|
228
|
+
if (field.dataType) {
|
|
229
|
+
const dataTypeNode = addressSpace.findDataType(field.dataType);
|
|
230
|
+
// istanbul ignore next
|
|
231
|
+
if (dataTypeNode && dataTypeNode.isSupertypeOf(structure)) {
|
|
232
|
+
// sub structure .. let make an handler too
|
|
233
|
+
const camelCaseName = (0, node_opcua_utils_1.lowerFirstLetter)(field.name);
|
|
234
|
+
const subExtObj = uaVariable.$extensionObject[camelCaseName];
|
|
235
|
+
if (subExtObj) {
|
|
236
|
+
uaVariable.$extensionObject[camelCaseName] = new Proxy(subExtObj, makeHandler(() => {
|
|
237
|
+
return uaVariable.getComponentByName(field.name);
|
|
238
|
+
}));
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
warningLog("extension object is null");
|
|
242
|
+
}
|
|
198
243
|
}
|
|
199
|
-
const value = prepareVariantValue(dataType, propertyValue);
|
|
200
|
-
propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
201
|
-
propertyNode.$dataValue.value.dataType = dataType;
|
|
202
|
-
propertyNode.$dataValue.value.value = value;
|
|
203
|
-
return new node_opcua_data_value_1.DataValue(propertyNode.$dataValue);
|
|
204
|
-
},
|
|
205
|
-
timestamped_set: (_dataValue, callback) => {
|
|
206
|
-
callback(null, node_opcua_status_code_1.StatusCodes.BadNotWritable);
|
|
207
244
|
}
|
|
208
|
-
}
|
|
245
|
+
}
|
|
209
246
|
}
|
|
210
|
-
function _installExtensionObjectBindingOnProperties(
|
|
211
|
-
|
|
212
|
-
|
|
247
|
+
function _installExtensionObjectBindingOnProperties(uaVariable, options) {
|
|
248
|
+
// may be extension object mechanism has alreday been install
|
|
249
|
+
// in this case we just need to rebind the properties...
|
|
250
|
+
if (uaVariable.$extensionObject) {
|
|
251
|
+
const extObj = uaVariable.$extensionObject;
|
|
252
|
+
uaVariable.bindExtensionObject(extObj, { createMissingProp: true, force: true });
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (uaVariable.$$extensionObjectArray) {
|
|
256
|
+
const extObj = uaVariable.$$extensionObjectArray;
|
|
257
|
+
_bindExtensionObjectArrayOrMatrix(uaVariable, extObj, { createMissingProp: true, force: true });
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const dataValue = uaVariable.readValue();
|
|
261
|
+
const extObj = dataValue.value.value;
|
|
262
|
+
if (extObj instanceof node_opcua_extension_object_1.ExtensionObject) {
|
|
263
|
+
uaVariable.bindExtensionObject(extObj, { createMissingProp: true, force: true });
|
|
264
|
+
}
|
|
265
|
+
else if (extObj instanceof Array) {
|
|
266
|
+
// istanbul ignore else
|
|
267
|
+
if (dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Array || dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Matrix) {
|
|
268
|
+
_bindExtensionObjectArrayOrMatrix(uaVariable, extObj, { createMissingProp: true, force: true });
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
throw new Error("Internal Error, unexpected case");
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
exports._installExtensionObjectBindingOnProperties = _installExtensionObjectBindingOnProperties;
|
|
276
|
+
function _installFields2(uaVariable, { get, set }, options) {
|
|
277
|
+
options = options || { createMissingProp: false };
|
|
278
|
+
const dt = uaVariable.getDataTypeNode();
|
|
213
279
|
const definition = dt.getStructureDefinition();
|
|
214
280
|
for (const field of definition.fields || []) {
|
|
215
|
-
// istanbul ignore next
|
|
216
281
|
if (node_opcua_nodeid_1.NodeId.sameNodeId(node_opcua_nodeid_1.NodeId.nullNodeId, field.dataType)) {
|
|
217
282
|
warningLog("field.dataType is null ! ", field.name, node_opcua_nodeid_1.NodeId.nullNodeId.toString());
|
|
218
283
|
warningLog(field.toString());
|
|
219
284
|
warningLog(" dataType replaced with BaseDataType ");
|
|
220
285
|
warningLog(definition.toString());
|
|
221
|
-
field.dataType =
|
|
286
|
+
field.dataType = uaVariable.resolveNodeId("BaseDataType");
|
|
222
287
|
}
|
|
223
|
-
const propertyNode = getOrCreateProperty(
|
|
288
|
+
const propertyNode = getOrCreateProperty(uaVariable, field, options);
|
|
224
289
|
if (!propertyNode) {
|
|
225
290
|
continue;
|
|
226
291
|
}
|
|
227
292
|
propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
228
|
-
propertyNode.
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
293
|
+
propertyNode.$dataValue.sourceTimestamp = uaVariable.$dataValue.sourceTimestamp;
|
|
294
|
+
propertyNode.$dataValue.sourcePicoseconds = uaVariable.$dataValue.sourcePicoseconds;
|
|
295
|
+
propertyNode.$dataValue.serverTimestamp = uaVariable.$dataValue.serverTimestamp;
|
|
296
|
+
propertyNode.$dataValue.serverPicoseconds = uaVariable.$dataValue.serverPicoseconds;
|
|
297
|
+
propertyNode.$dataValue.value.dataType = propertyNode.dataTypeObj.basicDataType;
|
|
298
|
+
propertyNode.$dataValue.value.arrayType = propertyNode.valueRank === -1 ? node_opcua_variant_1.VariantArrayType.Scalar : (propertyNode.valueRank === 1 ? node_opcua_variant_1.VariantArrayType.Array : node_opcua_variant_1.VariantArrayType.Matrix);
|
|
299
|
+
propertyNode.$dataValue.value.dimensions = propertyNode.valueRank > 1 ? propertyNode.arrayDimensions : null;
|
|
300
|
+
const fieldName = field.name;
|
|
301
|
+
installDataValueGetter(propertyNode, () => get(fieldName));
|
|
302
|
+
(0, node_opcua_assert_1.default)(propertyNode._inner_replace_dataValue);
|
|
303
|
+
propertyNode._inner_replace_dataValue = (dataValue, indexRange) => {
|
|
304
|
+
/** */
|
|
305
|
+
const sourceTime = (0, node_opcua_date_time_1.coerceClock)(dataValue.sourceTimestamp, dataValue.sourcePicoseconds);
|
|
306
|
+
const value = dataValue.value.value;
|
|
307
|
+
set(field.name, value, sourceTime);
|
|
308
|
+
};
|
|
309
|
+
if (propertyNode.dataTypeObj.basicDataType === node_opcua_variant_1.DataType.ExtensionObject) {
|
|
310
|
+
_installFields2(propertyNode, {
|
|
311
|
+
get: (fieldName) => {
|
|
312
|
+
const mainFieldName = field.name;
|
|
313
|
+
return get(mainFieldName)[(0, node_opcua_utils_1.lowerFirstLetter)(fieldName)];
|
|
314
|
+
},
|
|
315
|
+
set: (fieldName, value, sourceTime) => {
|
|
316
|
+
const mainFieldName = field.name;
|
|
317
|
+
get(mainFieldName)[(0, node_opcua_utils_1.lowerFirstLetter)(fieldName)] = value;
|
|
318
|
+
}
|
|
319
|
+
}, options);
|
|
234
320
|
}
|
|
235
|
-
const camelCaseName = (0, node_opcua_utils_1.lowerFirstLetter)(field.name);
|
|
236
|
-
// assert(Object.prototype.hasOwnProperty.call(variableNode.$extensionObject, camelCaseName));
|
|
237
|
-
if (variableNode.$extensionObject[camelCaseName] !== undefined && basicDataType === node_opcua_variant_1.DataType.ExtensionObject) {
|
|
238
|
-
propertyNode.bindExtensionObject(variableNode.$extensionObject[camelCaseName], Object.assign(Object.assign({}, options), { force: true }));
|
|
239
|
-
// replace upwards
|
|
240
|
-
variableNode.$extensionObject[camelCaseName] = propertyNode.$extensionObject;
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
const prop = variableNode.$extensionObject[camelCaseName];
|
|
244
|
-
if (prop === undefined) {
|
|
245
|
-
propertyNode._internal_set_value(new node_opcua_variant_1.Variant({
|
|
246
|
-
dataType: node_opcua_variant_1.DataType.Null
|
|
247
|
-
}));
|
|
248
|
-
}
|
|
249
|
-
else {
|
|
250
|
-
const preparedValue = prepareVariantValue(basicDataType, prop);
|
|
251
|
-
propertyNode._internal_set_value(new node_opcua_variant_1.Variant({
|
|
252
|
-
dataType: basicDataType,
|
|
253
|
-
value: preparedValue
|
|
254
|
-
}));
|
|
255
|
-
}
|
|
256
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
257
|
-
// property.camelCaseName = camelCaseName;
|
|
258
|
-
propertyNode.setValueFromSource = function (variant) {
|
|
259
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
260
|
-
const inner_this = this;
|
|
261
|
-
const variant1 = node_opcua_variant_1.Variant.coerce(variant);
|
|
262
|
-
inner_this.verifyVariantCompatibility(variant1);
|
|
263
|
-
// because self.$extensionObject is a Proxy with handlers that
|
|
264
|
-
// cascade the chagne we do not need to call touchValue() here
|
|
265
|
-
variableNode.$extensionObject[camelCaseName] = variant1.value;
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
(0, node_opcua_assert_1.default)(propertyNode.readValue().statusCode.equals(node_opcua_status_code_1.StatusCodes.Good));
|
|
269
|
-
bindProperty(variableNode, propertyNode, camelCaseName, basicDataType);
|
|
270
321
|
}
|
|
271
322
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
323
|
+
function installDataValueGetter(propertyNode, get) {
|
|
324
|
+
Object.defineProperty(propertyNode.$dataValue.value, "value", { get });
|
|
325
|
+
const $ = propertyNode.$dataValue;
|
|
326
|
+
Object.defineProperty(propertyNode, "$dataValue", {
|
|
327
|
+
get() {
|
|
328
|
+
return $;
|
|
329
|
+
},
|
|
330
|
+
set: (value) => {
|
|
331
|
+
throw new Error("$dataValue is now frozen and should not be modified this way !\n contact sterfive.com");
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
function isVariableContainingExtensionObject(uaVariable) {
|
|
336
|
+
const addressSpace = uaVariable.addressSpace;
|
|
278
337
|
const structure = addressSpace.findDataType("Structure");
|
|
279
|
-
let extensionObject_;
|
|
280
338
|
if (!structure) {
|
|
281
339
|
// the addressSpace is limited and doesn't provide extension object
|
|
282
340
|
// bindExtensionObject cannot be performed and shall finish here.
|
|
283
|
-
return
|
|
341
|
+
return false;
|
|
284
342
|
}
|
|
285
343
|
(0, node_opcua_assert_1.default)(structure.browseName.toString() === "Structure", "expecting DataType Structure to be in IAddressSpace");
|
|
286
|
-
const dt =
|
|
344
|
+
const dt = uaVariable.getDataTypeNode();
|
|
287
345
|
if (!dt.isSupertypeOf(structure)) {
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
function _innerBindExtensionObjectScalar(uaVariable, { get, set }, options) {
|
|
351
|
+
uaVariable.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
352
|
+
uaVariable.$dataValue.value.dataType = node_opcua_variant_1.DataType.ExtensionObject;
|
|
353
|
+
uaVariable.$dataValue.value.arrayType = node_opcua_variant_1.VariantArrayType.Scalar;
|
|
354
|
+
uaVariable.setValueFromSource = function (variant) {
|
|
355
|
+
setExtensionObjectPartialValue(this, variant.value);
|
|
356
|
+
};
|
|
357
|
+
installDataValueGetter(uaVariable, get);
|
|
358
|
+
(0, node_opcua_assert_1.default)(uaVariable._inner_replace_dataValue);
|
|
359
|
+
uaVariable._inner_replace_dataValue = (dataValue, indexRange) => {
|
|
360
|
+
/** */
|
|
361
|
+
const ext = dataValue.value.value;
|
|
362
|
+
const sourceTime = (0, node_opcua_date_time_1.coerceClock)(dataValue.sourceTimestamp, dataValue.sourcePicoseconds);
|
|
363
|
+
set(ext, sourceTime);
|
|
364
|
+
};
|
|
365
|
+
_installFields2(uaVariable, {
|
|
366
|
+
get: (fieldName) => {
|
|
367
|
+
const extObj = get();
|
|
368
|
+
return extObj[(0, node_opcua_utils_1.lowerFirstLetter)(fieldName)];
|
|
369
|
+
},
|
|
370
|
+
set: (fieldName, value, sourceTime) => {
|
|
371
|
+
const extObj = get();
|
|
372
|
+
extObj[(0, node_opcua_utils_1.lowerFirstLetter)(fieldName)] = value;
|
|
373
|
+
//1 propagateTouchValueDownward(uaVariable, sourceTime);
|
|
374
|
+
//1 propagateTouchValueUpward(uaVariable, sourceTime);
|
|
375
|
+
}
|
|
376
|
+
}, options);
|
|
377
|
+
}
|
|
378
|
+
function _bindExtensionObject(uaVariable, optionalExtensionObject, options) {
|
|
379
|
+
var _a, _b;
|
|
380
|
+
options = options || { createMissingProp: false };
|
|
381
|
+
if (!isVariableContainingExtensionObject(uaVariable)) {
|
|
288
382
|
return null;
|
|
289
383
|
}
|
|
290
|
-
|
|
384
|
+
const addressSpace = uaVariable.addressSpace;
|
|
385
|
+
let extensionObject_;
|
|
386
|
+
// istanbul ignore next
|
|
387
|
+
if (uaVariable.valueRank !== -1 && uaVariable.valueRank !== 1) {
|
|
291
388
|
throw new Error("Cannot bind an extension object here, valueRank must be scalar (-1) or one-dimensional (1)");
|
|
292
389
|
}
|
|
293
390
|
// istanbul ignore next
|
|
294
|
-
|
|
295
|
-
debugLog(" ------------------------------ binding ", self.browseName.toString(), self.nodeId.toString());
|
|
296
|
-
}
|
|
391
|
+
doDebug && debugLog(" ------------------------------ binding ", uaVariable.browseName.toString(), uaVariable.nodeId.toString());
|
|
297
392
|
// ignore bindExtensionObject on sub extension object, bindExtensionObject has to be called from the top most object
|
|
298
393
|
if (!options.force &&
|
|
299
|
-
|
|
300
|
-
(
|
|
301
|
-
const parentDataType =
|
|
394
|
+
uaVariable.parent &&
|
|
395
|
+
(uaVariable.parent.nodeClass === node_opcua_data_model_1.NodeClass.Variable || uaVariable.parent.nodeClass === node_opcua_data_model_1.NodeClass.VariableType)) {
|
|
396
|
+
const parentDataType = uaVariable.parent.dataType;
|
|
302
397
|
const dataTypeNode = addressSpace.findNode(parentDataType);
|
|
398
|
+
const structure = addressSpace.findDataType("Structure");
|
|
303
399
|
// istanbul ignore next
|
|
304
400
|
if (dataTypeNode && dataTypeNode.isSupertypeOf(structure)) {
|
|
305
401
|
// warningLog(
|
|
@@ -313,98 +409,182 @@ function _bindExtensionObject(self, optionalExtensionObject, options) {
|
|
|
313
409
|
}
|
|
314
410
|
}
|
|
315
411
|
// -------------------- make sure we do not bind a variable twice ....
|
|
316
|
-
if (
|
|
412
|
+
if (uaVariable.$extensionObject && !optionalExtensionObject) {
|
|
317
413
|
// istanbul ignore next
|
|
318
|
-
if (!
|
|
319
|
-
warningLog("on node : ",
|
|
320
|
-
warningLog((_a =
|
|
414
|
+
if (!uaVariable.checkExtensionObjectIsCorrect(uaVariable.$extensionObject)) {
|
|
415
|
+
warningLog("on node : ", uaVariable.browseName.toString(), uaVariable.nodeId.toString(), "dataType=", uaVariable.dataType.toString({ addressSpace: uaVariable.addressSpace }));
|
|
416
|
+
warningLog((_a = uaVariable.$extensionObject) === null || _a === void 0 ? void 0 : _a.toString());
|
|
321
417
|
throw new Error("bindExtensionObject: $extensionObject is incorrect: we are expecting a " +
|
|
322
|
-
|
|
418
|
+
uaVariable.dataType.toString({ addressSpace: uaVariable.addressSpace }) +
|
|
323
419
|
" but we got a " +
|
|
324
|
-
((_b =
|
|
420
|
+
((_b = uaVariable.$extensionObject) === null || _b === void 0 ? void 0 : _b.constructor.name));
|
|
325
421
|
}
|
|
326
|
-
return
|
|
327
|
-
// throw new Error("Variable already bound");
|
|
422
|
+
return uaVariable.$extensionObject;
|
|
328
423
|
}
|
|
329
|
-
// ------------------------------------------------------
|
|
330
|
-
// make sure we have a structure
|
|
331
|
-
// ------------------------------------------------------
|
|
332
|
-
const s = self.readValue();
|
|
333
424
|
// istanbul ignore next
|
|
334
|
-
if (
|
|
335
|
-
warningLog("Warning the DataType associated with this Variable is abstract ",
|
|
425
|
+
if (uaVariable.dataTypeObj.isAbstract) {
|
|
426
|
+
warningLog("Warning the DataType associated with this Variable is abstract ", uaVariable.dataTypeObj.browseName.toString());
|
|
336
427
|
warningLog("You need to provide a extension object yourself ");
|
|
337
428
|
throw new Error("bindExtensionObject requires a extensionObject as associated dataType is only abstract");
|
|
338
429
|
}
|
|
430
|
+
const s = uaVariable.readValue();
|
|
339
431
|
if (s.value && s.value.dataType === node_opcua_variant_1.DataType.ExtensionObject && s.value.value && optionalExtensionObject) {
|
|
340
432
|
// we want to replace the extension object
|
|
341
433
|
s.value.value = null;
|
|
342
434
|
}
|
|
343
435
|
innerBindExtensionObject();
|
|
344
|
-
(0, node_opcua_assert_1.default)(
|
|
345
|
-
return
|
|
436
|
+
(0, node_opcua_assert_1.default)(uaVariable.$extensionObject instanceof Object);
|
|
437
|
+
return uaVariable.$extensionObject;
|
|
346
438
|
function innerBindExtensionObject() {
|
|
347
439
|
if (s.value && (s.value.dataType === node_opcua_variant_1.DataType.Null || (s.value.dataType === node_opcua_variant_1.DataType.ExtensionObject && !s.value.value))) {
|
|
348
|
-
if (
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
return d;
|
|
357
|
-
},
|
|
358
|
-
timestamped_set(dataValue, callback) {
|
|
359
|
-
const ext = dataValue.value.value;
|
|
360
|
-
if (!self.checkExtensionObjectIsCorrect(ext)) {
|
|
361
|
-
return callback(null, node_opcua_status_code_1.StatusCodes.BadInvalidArgument);
|
|
362
|
-
}
|
|
363
|
-
_setExtensionObject(self, ext);
|
|
364
|
-
callback(null, node_opcua_status_code_1.StatusCodes.Good);
|
|
365
|
-
}
|
|
366
|
-
}, true);
|
|
367
|
-
_setExtensionObject(self, extensionObject_);
|
|
440
|
+
if (uaVariable.valueRank === -1 /** Scalar */) {
|
|
441
|
+
extensionObject_ = optionalExtensionObject || addressSpace.constructExtensionObject(uaVariable.dataType, {});
|
|
442
|
+
installExt(uaVariable, extensionObject_);
|
|
443
|
+
_innerBindExtensionObjectScalar(uaVariable, {
|
|
444
|
+
get: () => uaVariable.$extensionObject,
|
|
445
|
+
set: (value) => installExt(uaVariable, value)
|
|
446
|
+
}, options);
|
|
447
|
+
return;
|
|
368
448
|
}
|
|
369
|
-
else if (
|
|
370
|
-
|
|
371
|
-
extensionObject_ = optionalExtensionObject || [];
|
|
372
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
373
|
-
self.bindVariable({
|
|
374
|
-
timestamped_get() {
|
|
375
|
-
const d = new node_opcua_data_value_1.DataValue(self.$dataValue);
|
|
376
|
-
d.value.value = self.$extensionObject
|
|
377
|
-
? self.$extensionObject.map((e) => e.clone())
|
|
378
|
-
: null;
|
|
379
|
-
return d;
|
|
380
|
-
},
|
|
381
|
-
timestamped_set(dataValue, callback) {
|
|
382
|
-
const ext = dataValue.value.value;
|
|
383
|
-
if (!self.checkExtensionObjectIsCorrect(ext)) {
|
|
384
|
-
return callback(null, node_opcua_status_code_1.StatusCodes.BadInvalidArgument);
|
|
385
|
-
}
|
|
386
|
-
_setExtensionObject(self, ext);
|
|
387
|
-
callback(null, node_opcua_status_code_1.StatusCodes.Good);
|
|
388
|
-
}
|
|
389
|
-
}, true);
|
|
390
|
-
_setExtensionObject(self, extensionObject_);
|
|
449
|
+
else if (uaVariable.valueRank === 1 /** Array */) {
|
|
450
|
+
throw new Error("Should not get there ! Please fix me");
|
|
391
451
|
}
|
|
392
452
|
else {
|
|
393
|
-
errorLog(
|
|
394
|
-
errorLog("Unsupported case ! valueRank= ",
|
|
453
|
+
errorLog(uaVariable.toString());
|
|
454
|
+
errorLog("Unsupported case ! valueRank= ", uaVariable.valueRank);
|
|
395
455
|
}
|
|
396
456
|
}
|
|
397
457
|
else {
|
|
398
458
|
// verify that variant has the correct type
|
|
399
459
|
(0, node_opcua_assert_1.default)(s.value.dataType === node_opcua_variant_1.DataType.ExtensionObject);
|
|
400
|
-
|
|
401
|
-
(
|
|
402
|
-
|
|
460
|
+
installExt(uaVariable, s.value.value);
|
|
461
|
+
_innerBindExtensionObjectScalar(uaVariable, {
|
|
462
|
+
get: () => uaVariable.$extensionObject,
|
|
463
|
+
set: (value) => installExt(uaVariable, value)
|
|
464
|
+
}, options);
|
|
403
465
|
}
|
|
404
|
-
_installExtensionObjectBindingOnProperties(self, options);
|
|
405
466
|
}
|
|
406
467
|
}
|
|
407
468
|
exports._bindExtensionObject = _bindExtensionObject;
|
|
469
|
+
const getIndexAsText = (index) => {
|
|
470
|
+
if (typeof index === "number")
|
|
471
|
+
return `${index}`;
|
|
472
|
+
return `${index.map((a) => a.toString()).join(",")}`;
|
|
473
|
+
};
|
|
474
|
+
const composeBrowseNameAndNodeId = (uaVariable, indexes) => {
|
|
475
|
+
const iAsText = getIndexAsText(indexes);
|
|
476
|
+
const browseName = (0, node_opcua_data_model_1.coerceQualifiedName)(iAsText);
|
|
477
|
+
let nodeId;
|
|
478
|
+
if (uaVariable.nodeId.identifierType === node_opcua_nodeid_1.NodeIdType.STRING) {
|
|
479
|
+
nodeId = new node_opcua_nodeid_1.NodeId(node_opcua_nodeid_1.NodeIdType.STRING, uaVariable.nodeId.value + `[${iAsText}]`, uaVariable.nodeId.namespace);
|
|
480
|
+
}
|
|
481
|
+
return { browseName, nodeId };
|
|
482
|
+
};
|
|
483
|
+
// eslint-disable-next-line max-statements
|
|
484
|
+
function _bindExtensionObjectArrayOrMatrix(uaVariable, optionalExtensionObjectArray, options) {
|
|
485
|
+
// istanbul ignore next
|
|
486
|
+
if (uaVariable.valueRank < 1) {
|
|
487
|
+
throw new Error("Variable must be a MultiDimensional array");
|
|
488
|
+
}
|
|
489
|
+
const arrayDimensions = uaVariable.arrayDimensions || [];
|
|
490
|
+
// istanbul ignore next
|
|
491
|
+
if (!isVariableContainingExtensionObject(uaVariable)) {
|
|
492
|
+
return [];
|
|
493
|
+
}
|
|
494
|
+
if ((arrayDimensions.length === 0 || arrayDimensions.length === 1 && arrayDimensions[0] === 0) && optionalExtensionObjectArray) {
|
|
495
|
+
arrayDimensions[0] = optionalExtensionObjectArray.length;
|
|
496
|
+
}
|
|
497
|
+
const totalLength = arrayDimensions.reduce((p, c) => p * c, 1);
|
|
498
|
+
/** */
|
|
499
|
+
const addressSpace = uaVariable.addressSpace;
|
|
500
|
+
if (optionalExtensionObjectArray) {
|
|
501
|
+
if (optionalExtensionObjectArray.length !== totalLength) {
|
|
502
|
+
throw new Error(`optionalExtensionObjectArray must have the expected number of element matching ${arrayDimensions}`);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
if (!optionalExtensionObjectArray) {
|
|
506
|
+
optionalExtensionObjectArray = [];
|
|
507
|
+
for (let i = 0; i < totalLength; i++) {
|
|
508
|
+
optionalExtensionObjectArray[i] = addressSpace.constructExtensionObject(uaVariable.dataType, {});
|
|
509
|
+
;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
uaVariable.$$extensionObjectArray = optionalExtensionObjectArray;
|
|
513
|
+
uaVariable.$dataValue.value.arrayType = uaVariable.valueRank === 1 ? node_opcua_variant_1.VariantArrayType.Array : node_opcua_variant_1.VariantArrayType.Matrix;
|
|
514
|
+
uaVariable.$dataValue.value.dimensions = uaVariable.valueRank === 1 ? null : (uaVariable.arrayDimensions || []);
|
|
515
|
+
uaVariable.$dataValue.value.dataType = node_opcua_variant_1.DataType.ExtensionObject;
|
|
516
|
+
uaVariable.$dataValue.value.value = uaVariable.$$extensionObjectArray;
|
|
517
|
+
uaVariable.bindVariable({
|
|
518
|
+
get: () => uaVariable.$dataValue.value
|
|
519
|
+
}, true);
|
|
520
|
+
const namespace = uaVariable.namespace;
|
|
521
|
+
const indexIterator = new idx_iterator_1.IndexIterator(arrayDimensions);
|
|
522
|
+
for (let i = 0; i < totalLength; i++) {
|
|
523
|
+
const index = indexIterator.next();
|
|
524
|
+
const { browseName, nodeId } = composeBrowseNameAndNodeId(uaVariable, index);
|
|
525
|
+
let uaElement = uaVariable.getComponentByName(browseName);
|
|
526
|
+
if (!uaElement) {
|
|
527
|
+
uaElement = namespace.addVariable({
|
|
528
|
+
browseName,
|
|
529
|
+
nodeId,
|
|
530
|
+
componentOf: uaVariable,
|
|
531
|
+
dataType: uaVariable.dataType,
|
|
532
|
+
valueRank: -1,
|
|
533
|
+
accessLevel: uaVariable.accessLevel
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
uaElement.$dataValue.value.dataType = node_opcua_variant_1.DataType.ExtensionObject;
|
|
537
|
+
uaElement.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
538
|
+
uaElement.$dataValue.sourceTimestamp = uaVariable.$dataValue.sourceTimestamp;
|
|
539
|
+
uaElement.$dataValue.sourcePicoseconds = uaVariable.$dataValue.sourcePicoseconds;
|
|
540
|
+
uaElement.$dataValue.serverTimestamp = uaVariable.$dataValue.serverTimestamp;
|
|
541
|
+
uaElement.$dataValue.serverPicoseconds = uaVariable.$dataValue.serverPicoseconds;
|
|
542
|
+
uaElement.$dataValue.value.dataType = node_opcua_variant_1.DataType.ExtensionObject;
|
|
543
|
+
uaElement.$dataValue.value.arrayType = node_opcua_variant_1.VariantArrayType.Scalar;
|
|
544
|
+
{
|
|
545
|
+
const capturedIndex = i;
|
|
546
|
+
_innerBindExtensionObjectScalar(uaElement, {
|
|
547
|
+
get: () => uaVariable.$$extensionObjectArray[capturedIndex],
|
|
548
|
+
set: (newValue, sourceTimestamp) => {
|
|
549
|
+
uaVariable.$$extensionObjectArray[capturedIndex] = newValue;
|
|
550
|
+
uaVariable.touchValue();
|
|
551
|
+
propagateTouchValueDownward(uaVariable, sourceTimestamp);
|
|
552
|
+
propagateTouchValueUpward(uaVariable, sourceTimestamp);
|
|
553
|
+
},
|
|
554
|
+
}, Object.assign(Object.assign({}, options), { force: true }));
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return uaVariable.$$extensionObjectArray;
|
|
558
|
+
}
|
|
559
|
+
exports._bindExtensionObjectArrayOrMatrix = _bindExtensionObjectArrayOrMatrix;
|
|
560
|
+
function getElement(path, data) {
|
|
561
|
+
if (typeof path === "string") {
|
|
562
|
+
path = path.split(".");
|
|
563
|
+
}
|
|
564
|
+
let a = data;
|
|
565
|
+
for (const e of path) {
|
|
566
|
+
a = a[e];
|
|
567
|
+
}
|
|
568
|
+
return a;
|
|
569
|
+
}
|
|
570
|
+
exports.getElement = getElement;
|
|
571
|
+
function setElement(path, data, value) {
|
|
572
|
+
if (typeof path === "string") {
|
|
573
|
+
path = path.split(".");
|
|
574
|
+
}
|
|
575
|
+
const last = path.pop();
|
|
576
|
+
let a = data;
|
|
577
|
+
for (const e of path) {
|
|
578
|
+
a = a[e];
|
|
579
|
+
}
|
|
580
|
+
a[last] = value;
|
|
581
|
+
}
|
|
582
|
+
exports.setElement = setElement;
|
|
583
|
+
function incrementElement(path, data) {
|
|
584
|
+
const value = getElement(path, data);
|
|
585
|
+
setElement(path, data, value + 1);
|
|
586
|
+
}
|
|
587
|
+
exports.incrementElement = incrementElement;
|
|
408
588
|
function extractPartialData(path, extensionObject) {
|
|
409
589
|
let name;
|
|
410
590
|
if (typeof path === "string") {
|
|
@@ -431,7 +611,6 @@ function extractPartialData(path, extensionObject) {
|
|
|
431
611
|
}
|
|
432
612
|
name = path[path.length - 1];
|
|
433
613
|
c1[name] = c2[name];
|
|
434
|
-
c1[name] += 1;
|
|
435
614
|
return partialData;
|
|
436
615
|
}
|
|
437
616
|
exports.extractPartialData = extractPartialData;
|