node-opcua-address-space 2.66.2 → 2.68.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/address_space_ts.d.ts +0 -2
- package/dist/source/address_space_ts.js.map +1 -1
- package/dist/source/continuation_points/continuation_point_manager.js +6 -3
- package/dist/source/continuation_points/continuation_point_manager.js.map +1 -1
- package/dist/source/loader/make_xml_extension_object_parser.js +28 -9
- package/dist/source/loader/make_xml_extension_object_parser.js.map +1 -1
- package/dist/src/base_node_impl.js +1 -1
- package/dist/src/base_node_impl.js.map +1 -1
- package/dist/src/extension_object_array_node.js +31 -22
- package/dist/src/extension_object_array_node.js.map +1 -1
- package/dist/src/historical_access/address_space_historical_data_node.js +3 -3
- package/dist/src/historical_access/address_space_historical_data_node.js.map +1 -1
- package/dist/src/reference_impl.js +1 -1
- package/dist/src/reference_impl.js.map +1 -1
- package/dist/src/ua_variable_impl.d.ts +9 -8
- package/dist/src/ua_variable_impl.js +56 -313
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/dist/src/ua_variable_impl_ext_obj.d.ts +17 -0
- package/dist/src/ua_variable_impl_ext_obj.js +393 -0
- package/dist/src/ua_variable_impl_ext_obj.js.map +1 -0
- package/distNodeJS/generate_address_space.js +1 -1
- package/package.json +36 -36
- package/source/address_space_ts.ts +0 -2
- package/source/continuation_points/continuation_point_manager.ts +11 -9
- package/source/loader/make_xml_extension_object_parser.ts +32 -11
- package/source_nodejs/generate_address_space.ts +1 -1
- package/src/base_node_impl.ts +1 -1
- package/src/extension_object_array_node.ts +43 -28
- package/src/historical_access/address_space_historical_data_node.ts +3 -3
- package/src/reference_impl.ts +1 -1
- package/src/ua_variable_impl.ts +68 -381
- package/src/ua_variable_impl_ext_obj.ts +472 -0
- package/test_helpers/test_fixtures/issue_1132_variable_with_nodeid_value.xml +68 -0
- package/test_helpers/test_fixtures/nodeset_with_utf8_special_characters.xml +20 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { NodeId, NodeIdType } from "node-opcua-nodeid";
|
|
1
|
+
import { make_warningLog } from "node-opcua-debug";
|
|
2
|
+
import { coerceNodeId, NodeId, NodeIdType } from "node-opcua-nodeid";
|
|
3
3
|
import { EnumDefinition, StructureDefinition } from "node-opcua-types";
|
|
4
4
|
import { lowerFirstLetter } from "node-opcua-utils";
|
|
5
5
|
import { DataType } from "node-opcua-variant";
|
|
6
6
|
import { ReaderState, ReaderStateParserLike, ParserLike, XmlAttributes } from "node-opcua-xml2json";
|
|
7
7
|
|
|
8
|
+
const warningLog = make_warningLog(__filename);
|
|
9
|
+
|
|
8
10
|
const localizedTextReader: ReaderStateParserLike = {
|
|
9
11
|
init(this: any) {
|
|
10
12
|
this.localizedText = {};
|
|
@@ -28,6 +30,18 @@ const localizedTextReader: ReaderStateParserLike = {
|
|
|
28
30
|
}
|
|
29
31
|
};
|
|
30
32
|
|
|
33
|
+
function clamp(value: number, minValue: number, maxValue: number) {
|
|
34
|
+
if(value < minValue) {
|
|
35
|
+
warningLog(`invalid value range : ${value} < ${minValue} but should be [${minValue} , ${maxValue}]`);
|
|
36
|
+
return minValue;
|
|
37
|
+
}
|
|
38
|
+
if(value > maxValue) {
|
|
39
|
+
warningLog(`invalid value range : ${value} > ${maxValue} but should be [${minValue} , ${maxValue}]`);
|
|
40
|
+
return maxValue;
|
|
41
|
+
}
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
|
|
31
45
|
const partials: { [key: string]: ReaderStateParserLike } = {
|
|
32
46
|
LocalizedText: localizedTextReader,
|
|
33
47
|
String: {
|
|
@@ -66,28 +80,28 @@ const partials: { [key: string]: ReaderStateParserLike } = {
|
|
|
66
80
|
},
|
|
67
81
|
Byte: {
|
|
68
82
|
finish(this: any) {
|
|
69
|
-
this.value = parseInt(this.text, 10);
|
|
83
|
+
this.value = clamp(parseInt(this.text, 10), 0, 255);
|
|
70
84
|
}
|
|
71
85
|
},
|
|
72
86
|
SByte: {
|
|
73
87
|
finish(this: any) {
|
|
74
|
-
this.value = parseInt(this.text, 10);
|
|
88
|
+
this.value = clamp(parseInt(this.text, 10), -128, 127);
|
|
75
89
|
}
|
|
76
90
|
},
|
|
77
91
|
Int8: {
|
|
78
92
|
finish(this: any) {
|
|
79
|
-
this.value = parseInt(this.text, 10);
|
|
93
|
+
this.value = clamp(parseInt(this.text, 10), -128, 127);
|
|
80
94
|
}
|
|
81
95
|
},
|
|
82
96
|
|
|
83
97
|
Int16: {
|
|
84
98
|
finish(this: any) {
|
|
85
|
-
this.value = parseInt(this.text, 10);
|
|
99
|
+
this.value = clamp(parseInt(this.text, 10), -32768, 32767);
|
|
86
100
|
}
|
|
87
101
|
},
|
|
88
102
|
Int32: {
|
|
89
103
|
finish(this: any) {
|
|
90
|
-
this.value = parseInt(this.text, 10);
|
|
104
|
+
this.value = clamp(parseInt(this.text, 10), -2147483648, 2147483647);
|
|
91
105
|
}
|
|
92
106
|
},
|
|
93
107
|
Int64: {
|
|
@@ -98,19 +112,19 @@ const partials: { [key: string]: ReaderStateParserLike } = {
|
|
|
98
112
|
|
|
99
113
|
UInt8: {
|
|
100
114
|
finish(this: any) {
|
|
101
|
-
this.value = parseInt(this.text, 10);
|
|
115
|
+
this.value = clamp(parseInt(this.text, 10), 0, 255);
|
|
102
116
|
}
|
|
103
117
|
},
|
|
104
118
|
|
|
105
119
|
UInt16: {
|
|
106
120
|
finish(this: any) {
|
|
107
|
-
this.value = parseInt(this.text, 10);
|
|
121
|
+
this.value = clamp(parseInt(this.text, 10), 0, 65535);
|
|
108
122
|
}
|
|
109
123
|
},
|
|
110
124
|
|
|
111
125
|
UInt32: {
|
|
112
126
|
finish(this: any) {
|
|
113
|
-
this.value = parseInt(this.text, 10);
|
|
127
|
+
this.value = clamp(parseInt(this.text, 10), 0, 4294967295);
|
|
114
128
|
}
|
|
115
129
|
},
|
|
116
130
|
|
|
@@ -132,6 +146,13 @@ const partials: { [key: string]: ReaderStateParserLike } = {
|
|
|
132
146
|
/** to do */
|
|
133
147
|
console.log(" Missing Implemntation contact sterfive.com!");
|
|
134
148
|
}
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
NodeId: {
|
|
152
|
+
finish(this: any) {
|
|
153
|
+
// to do check Local or GMT
|
|
154
|
+
this.value = coerceNodeId(this.text);
|
|
155
|
+
}
|
|
135
156
|
}
|
|
136
157
|
};
|
|
137
158
|
|
|
@@ -239,7 +260,7 @@ function _makeTypeReader(
|
|
|
239
260
|
if (fieldParser.finish) {
|
|
240
261
|
fieldParser.finish.call(this);
|
|
241
262
|
} else {
|
|
242
|
-
|
|
263
|
+
warningLog("xxx check " + fieldTypename);
|
|
243
264
|
}
|
|
244
265
|
this.parent.value = this.parent.value || {};
|
|
245
266
|
this.parent.value[elName] = _clone(this.value);
|
|
@@ -18,7 +18,7 @@ export async function readNodeSet2XmlFile(xmlFile: string): Promise<string> {
|
|
|
18
18
|
throw new Error(msg);
|
|
19
19
|
}
|
|
20
20
|
debugLog(" parsing ", xmlFile);
|
|
21
|
-
const xmlData = await fs.promises.readFile(xmlFile, "
|
|
21
|
+
const xmlData = await fs.promises.readFile(xmlFile, "utf-8");
|
|
22
22
|
return xmlData;
|
|
23
23
|
}
|
|
24
24
|
export function generateAddressSpace(
|
package/src/base_node_impl.ts
CHANGED
|
@@ -1514,7 +1514,7 @@ function _propagate_ref(this: BaseNode, addressSpace: MinimalistAddressSpace, re
|
|
|
1514
1514
|
}
|
|
1515
1515
|
}
|
|
1516
1516
|
// xx ignore this assert(reference.nodeId.toString() !== this.nodeId.toString());
|
|
1517
|
-
// function w(s,l) { return (s+" ").
|
|
1517
|
+
// function w(s,l) { return (s+" ").substring(0,l);}
|
|
1518
1518
|
// if (reference.isForward) {
|
|
1519
1519
|
// console.log(" CHILD => ",w(related_node.browseName + " " + related_node.nodeId.toString(),30),
|
|
1520
1520
|
// " PARENT ",w(this.browseName + " " + this.nodeId.toString(),30) , reference.toString());
|
|
@@ -23,7 +23,7 @@ const errorLog = make_errorLog(__filename);
|
|
|
23
23
|
*
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
function getExtObjArrayNodeValue(this:
|
|
26
|
+
function getExtObjArrayNodeValue<T extends ExtensionObject>(this: UADynamicVariableArray<T>) {
|
|
27
27
|
return new Variant({
|
|
28
28
|
arrayType: VariantArrayType.Array,
|
|
29
29
|
dataType: DataType.ExtensionObject,
|
|
@@ -85,6 +85,7 @@ export function createExtObjArrayNode<T extends ExtensionObject>(parentFolder: U
|
|
|
85
85
|
const namespace = parentFolder.namespace;
|
|
86
86
|
|
|
87
87
|
const complexVariableType = addressSpace.findVariableType(options.complexVariableType);
|
|
88
|
+
// istanbul ignore next
|
|
88
89
|
if (!complexVariableType) {
|
|
89
90
|
throw new Error("cannot find complex variable type");
|
|
90
91
|
}
|
|
@@ -100,6 +101,8 @@ export function createExtObjArrayNode<T extends ExtensionObject>(parentFolder: U
|
|
|
100
101
|
assert(structure, "Structure Type not found: please check your nodeset file");
|
|
101
102
|
|
|
102
103
|
const dataType = addressSpace.findDataType(variableType.dataType);
|
|
104
|
+
|
|
105
|
+
// istanbul ignore next
|
|
103
106
|
if (!dataType) {
|
|
104
107
|
errorLog(variableType.toString());
|
|
105
108
|
throw new Error("cannot find Data Type");
|
|
@@ -123,7 +126,17 @@ export function createExtObjArrayNode<T extends ExtensionObject>(parentFolder: U
|
|
|
123
126
|
|
|
124
127
|
return uaArrayVariableNode;
|
|
125
128
|
}
|
|
129
|
+
function _getElementBrowseName<T extends ExtensionObject>(this: UADynamicVariableArray<T>, extObj: ExtensionObject) {
|
|
130
|
+
const indexPropertyName1 = this.$$indexPropertyName;
|
|
126
131
|
|
|
132
|
+
if (!Object.prototype.hasOwnProperty.call(extObj, indexPropertyName1)) {
|
|
133
|
+
console.log(" extension object do not have ", indexPropertyName1, extObj);
|
|
134
|
+
}
|
|
135
|
+
// assert(extObj.constructor === addressSpace.constructExtensionObject(dataType));
|
|
136
|
+
assert(Object.prototype.hasOwnProperty.call(extObj, indexPropertyName1));
|
|
137
|
+
const browseName = (extObj as any)[indexPropertyName1].toString();
|
|
138
|
+
return browseName;
|
|
139
|
+
};
|
|
127
140
|
/**
|
|
128
141
|
* @method bindExtObjArrayNode
|
|
129
142
|
* @param uaArrayVariableNode
|
|
@@ -136,57 +149,54 @@ export function bindExtObjArrayNode<T extends ExtensionObject>(
|
|
|
136
149
|
variableTypeNodeId: string | NodeId,
|
|
137
150
|
indexPropertyName: string
|
|
138
151
|
): UAVariable {
|
|
152
|
+
|
|
153
|
+
assert(uaArrayVariableNode.valueRank === 1, "expecting a one dimension array");
|
|
154
|
+
|
|
139
155
|
const addressSpace = uaArrayVariableNode.addressSpace;
|
|
140
156
|
|
|
141
157
|
const variableType = addressSpace.findVariableType(variableTypeNodeId);
|
|
142
|
-
|
|
158
|
+
|
|
159
|
+
// istanbul ignore next
|
|
160
|
+
if (!variableType || variableType.nodeId.isEmpty()) {
|
|
143
161
|
throw new Error("Cannot find VariableType " + variableTypeNodeId.toString());
|
|
144
162
|
}
|
|
145
|
-
assert(!variableType.nodeId.isEmpty());
|
|
146
163
|
|
|
147
|
-
|
|
148
|
-
|
|
164
|
+
const structure = addressSpace.findDataType("Structure");
|
|
165
|
+
|
|
166
|
+
// istanbul ignore next
|
|
167
|
+
if (!structure) {
|
|
168
|
+
throw new Error("Structure Type not found: please check your nodeset file");
|
|
169
|
+
}
|
|
149
170
|
|
|
150
171
|
let dataType = addressSpace.findDataType(variableType.dataType);
|
|
172
|
+
|
|
173
|
+
// istanbul ignore next
|
|
151
174
|
if (!dataType) {
|
|
152
175
|
throw new Error("Cannot find DataType " + variableType.dataType.toString());
|
|
153
176
|
}
|
|
154
|
-
|
|
177
|
+
|
|
178
|
+
assert(dataType.isSupertypeOf(structure), "expecting a structure (= ExtensionObject) here ");
|
|
155
179
|
|
|
156
180
|
assert(!uaArrayVariableNode.$$variableType, "uaArrayVariableNode has already been bound !");
|
|
157
181
|
|
|
158
182
|
uaArrayVariableNode.$$variableType = variableType;
|
|
159
183
|
|
|
160
|
-
structure = addressSpace.findDataType("Structure");
|
|
161
|
-
assert(structure, "Structure Type not found: please check your nodeset file");
|
|
162
|
-
|
|
163
184
|
// verify that an object with same doesn't already exist
|
|
164
185
|
dataType = addressSpace.findDataType(variableType.dataType)! as UADataType;
|
|
165
|
-
assert(dataType!.isSupertypeOf(structure
|
|
186
|
+
assert(dataType!.isSupertypeOf(structure), "expecting a structure (= ExtensionObject) here ");
|
|
166
187
|
|
|
167
188
|
uaArrayVariableNode.$$dataType = dataType;
|
|
168
189
|
uaArrayVariableNode.$$extensionObjectArray = [];
|
|
169
190
|
uaArrayVariableNode.$$indexPropertyName = indexPropertyName;
|
|
170
191
|
|
|
171
|
-
uaArrayVariableNode.$$getElementBrowseName =
|
|
172
|
-
const indexPropertyName1 = this.$$indexPropertyName;
|
|
192
|
+
uaArrayVariableNode.$$getElementBrowseName = _getElementBrowseName;
|
|
173
193
|
|
|
174
|
-
|
|
175
|
-
console.log(" extension object do not have ", indexPropertyName1, extObj);
|
|
176
|
-
}
|
|
177
|
-
// assert(extObj.constructor === addressSpace.constructExtensionObject(dataType));
|
|
178
|
-
assert(Object.prototype.hasOwnProperty.call(extObj, indexPropertyName1));
|
|
179
|
-
const browseName = (extObj as any)[indexPropertyName1].toString();
|
|
180
|
-
return browseName;
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
const options = {
|
|
194
|
+
const bindOptions: any = {
|
|
184
195
|
get: getExtObjArrayNodeValue,
|
|
185
196
|
set: undefined // readonly
|
|
186
197
|
};
|
|
187
|
-
|
|
188
198
|
// bind the readonly
|
|
189
|
-
uaArrayVariableNode.bindVariable(
|
|
199
|
+
uaArrayVariableNode.bindVariable(bindOptions, true);
|
|
190
200
|
|
|
191
201
|
return uaArrayVariableNode;
|
|
192
202
|
}
|
|
@@ -258,12 +268,12 @@ export function addElement<T extends ExtensionObject>(
|
|
|
258
268
|
componentOf: uaArrayVariableNode.nodeId,
|
|
259
269
|
value: { dataType: DataType.ExtensionObject, value: extensionObject }
|
|
260
270
|
}) as UAVariableImpl;
|
|
261
|
-
elVar.bindExtensionObject();
|
|
271
|
+
elVar.bindExtensionObject(extensionObject, { force: true });
|
|
262
272
|
elVar.$extensionObject = extensionObject;
|
|
263
273
|
}
|
|
264
274
|
|
|
265
275
|
// also add the value inside
|
|
266
|
-
uaArrayVariableNode.$$extensionObjectArray.push(extensionObject);
|
|
276
|
+
uaArrayVariableNode.$$extensionObjectArray.push(elVar.$extensionObject);
|
|
267
277
|
|
|
268
278
|
return elVar;
|
|
269
279
|
}
|
|
@@ -288,11 +298,14 @@ export function removeElement<T extends ExtensionObject>(
|
|
|
288
298
|
uaArrayVariableNode: UADynamicVariableArray<T>,
|
|
289
299
|
element: any /* number | UAVariable | (a any) => boolean | ExtensionObject */
|
|
290
300
|
): void {
|
|
291
|
-
assert(element, "element must exist");
|
|
301
|
+
assert(element, "removeElement: element must exist");
|
|
292
302
|
const _array = uaArrayVariableNode.$$extensionObjectArray;
|
|
303
|
+
|
|
304
|
+
// istanbul ignore next
|
|
293
305
|
if (_array.length === 0) {
|
|
294
306
|
throw new Error(" cannot remove an element from an empty array ");
|
|
295
307
|
}
|
|
308
|
+
|
|
296
309
|
let elementIndex = -1;
|
|
297
310
|
|
|
298
311
|
if (typeof element === "number") {
|
|
@@ -314,8 +327,10 @@ export function removeElement<T extends ExtensionObject>(
|
|
|
314
327
|
assert(_array[0].constructor.name === (element as any).constructor.name, "element must match");
|
|
315
328
|
elementIndex = _array.findIndex((x: any) => x === element);
|
|
316
329
|
}
|
|
330
|
+
|
|
331
|
+
// istanbul ignore next
|
|
317
332
|
if (elementIndex < 0) {
|
|
318
|
-
throw new Error(" cannot find element matching " + element.toString());
|
|
333
|
+
throw new Error("removeElement: cannot find element matching " + element.toString());
|
|
319
334
|
}
|
|
320
335
|
return removeElementByIndex(uaArrayVariableNode, elementIndex);
|
|
321
336
|
}
|
|
@@ -172,7 +172,7 @@ export class VariableHistorian implements IVariableHistorian {
|
|
|
172
172
|
reverseDataValue: boolean,
|
|
173
173
|
callback: CallbackT<DataValue[]>
|
|
174
174
|
): void {
|
|
175
|
-
assert(callback
|
|
175
|
+
assert(typeof callback === 'function');
|
|
176
176
|
|
|
177
177
|
let dataValues = filter_dequeue(this._timeline, historyReadRawModifiedDetails, maxNumberToExtract, isReversed);
|
|
178
178
|
|
|
@@ -322,7 +322,7 @@ function _historyReadRawAsync(
|
|
|
322
322
|
reverseDataValue: boolean,
|
|
323
323
|
callback: CallbackT<DataValue[]>
|
|
324
324
|
) {
|
|
325
|
-
assert(callback
|
|
325
|
+
assert(typeof callback === 'function');
|
|
326
326
|
this.varHistorian!.extractDataValues(historyReadRawModifiedDetails, maxNumberToExtract, isReversed, reverseDataValue, callback);
|
|
327
327
|
}
|
|
328
328
|
|
|
@@ -546,7 +546,7 @@ function _historyRead(
|
|
|
546
546
|
continuationData: ContinuationData,
|
|
547
547
|
callback: CallbackT<HistoryReadResult>
|
|
548
548
|
) {
|
|
549
|
-
assert(callback
|
|
549
|
+
assert(typeof callback === 'function');
|
|
550
550
|
if (historyReadDetails instanceof ReadRawModifiedDetails) {
|
|
551
551
|
// note: only ReadRawModifiedDetails supported at this time
|
|
552
552
|
return this._historyReadRawModify(context, historyReadDetails, indexRange, dataEncoding, continuationData, callback);
|
package/src/reference_impl.ts
CHANGED
|
@@ -50,7 +50,7 @@ function _arrow(text: string, length: number, isForward: boolean): string {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
function _w(str: string, width: number): string {
|
|
53
|
-
return (
|
|
53
|
+
return str.padEnd(width).substring(0, width);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function _localCoerceToNodeID(nodeIdLike: string | NodeIdLike | { nodeId: NodeId }): NodeId {
|