node-opcua-client-dynamic-extension-object 2.162.0 → 2.163.1
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/convert_data_type_definition_to_structuretype_schema.d.ts +4 -3
- package/dist/convert_data_type_definition_to_structuretype_schema.js +96 -66
- package/dist/convert_data_type_definition_to_structuretype_schema.js.map +1 -1
- package/dist/extra_data_type_manager.d.ts +10 -1
- package/dist/extra_data_type_manager.js +96 -2
- package/dist/extra_data_type_manager.js.map +1 -1
- package/dist/get_extension_object_constructor.js +4 -4
- package/dist/get_extension_object_constructor.js.map +1 -1
- package/dist/get_extra_data_type_manager.d.ts +2 -1
- package/dist/get_extra_data_type_manager.js +8 -2
- package/dist/get_extra_data_type_manager.js.map +1 -1
- package/dist/populate_data_type_manager.d.ts +2 -4
- package/dist/populate_data_type_manager.js +88 -81
- package/dist/populate_data_type_manager.js.map +1 -1
- package/dist/private/populate_data_type_manager_103.js +5 -4
- package/dist/private/populate_data_type_manager_103.js.map +1 -1
- package/dist/private/populate_data_type_manager_104.d.ts +1 -2
- package/dist/private/populate_data_type_manager_104.js +41 -18
- package/dist/private/populate_data_type_manager_104.js.map +1 -1
- package/dist/resolve_dynamic_extension_object.d.ts +2 -2
- package/dist/resolve_dynamic_extension_object.js +66 -91
- package/dist/resolve_dynamic_extension_object.js.map +1 -1
- package/package.json +12 -12
- package/source/convert_data_type_definition_to_structuretype_schema.ts +116 -79
- package/source/extra_data_type_manager.ts +113 -4
- package/source/get_extension_object_constructor.ts +5 -4
- package/source/get_extra_data_type_manager.ts +15 -7
- package/source/populate_data_type_manager.ts +99 -89
- package/source/private/populate_data_type_manager_103.ts +6 -4
- package/source/private/populate_data_type_manager_104.ts +67 -28
- package/source/resolve_dynamic_extension_object.ts +79 -110
|
@@ -1,92 +1,62 @@
|
|
|
1
1
|
import { BinaryStream } from "node-opcua-binary-stream";
|
|
2
2
|
import { ExtensionObject, OpaqueStructure } from "node-opcua-extension-object";
|
|
3
3
|
import { DataType, Variant, VariantArrayType } from "node-opcua-variant";
|
|
4
|
-
import {
|
|
4
|
+
import { make_warningLog } from "node-opcua-debug";
|
|
5
5
|
import { IBasicSessionAsync2 } from "node-opcua-pseudo-session";
|
|
6
|
-
import {
|
|
7
|
-
import { ConstructorFunc, StructuredTypeField } from "node-opcua-factory";
|
|
8
|
-
import { BrowseDirection, NodeClassMask, ResultMask } from "node-opcua-data-model";
|
|
6
|
+
import { StructuredTypeField } from "node-opcua-factory";
|
|
9
7
|
//
|
|
10
8
|
import { ExtraDataTypeManager } from "./extra_data_type_manager";
|
|
11
|
-
import { readDataTypeDefinitionAndBuildType } from "./private/populate_data_type_manager_104";
|
|
12
9
|
|
|
13
10
|
const warningLog = make_warningLog(__filename);
|
|
14
11
|
|
|
15
|
-
async function getOrExtractConstructor(
|
|
16
|
-
session: IBasicSessionAsync2,
|
|
17
|
-
binaryEncodingNodeId: NodeId,
|
|
18
|
-
dataTypeManager: ExtraDataTypeManager
|
|
19
|
-
): Promise<ConstructorFunc> {
|
|
20
|
-
const dataTypeFactory = dataTypeManager.getDataTypeFactoryForNamespace(binaryEncodingNodeId.namespace);
|
|
21
|
-
|
|
22
|
-
const Constructor = dataTypeFactory.getConstructor(binaryEncodingNodeId);
|
|
23
|
-
if (Constructor) {
|
|
24
|
-
return Constructor;
|
|
25
|
-
}
|
|
26
|
-
if (binaryEncodingNodeId.namespace === 0) {
|
|
27
|
-
throw new Error("Internal Error");
|
|
28
|
-
}
|
|
29
|
-
// need to extract it
|
|
30
|
-
const browseResult = await session.browse({
|
|
31
|
-
nodeId: binaryEncodingNodeId,
|
|
32
|
-
referenceTypeId: "HasEncoding",
|
|
33
|
-
browseDirection: BrowseDirection.Inverse,
|
|
34
|
-
includeSubtypes: false,
|
|
35
|
-
nodeClassMask: NodeClassMask.DataType,
|
|
36
|
-
resultMask: ResultMask.BrowseName
|
|
37
|
-
});
|
|
38
|
-
if (browseResult.statusCode.isNotGood() || browseResult.references!.length !== 1) {
|
|
39
|
-
throw new Error("browse failed");
|
|
40
|
-
}
|
|
41
|
-
const r = browseResult.references![0];
|
|
42
|
-
const dataTypeNodeId = r.nodeId;
|
|
43
|
-
|
|
44
|
-
if (dataTypeFactory.getStructureInfoForDataType(dataTypeNodeId)) {
|
|
45
|
-
throw new Error("Internal Error: we are not expecting this dataType to be processed already " + dataTypeNodeId.toString());
|
|
46
|
-
}
|
|
47
|
-
await readDataTypeDefinitionAndBuildType(session, dataTypeNodeId, r.browseName.name!, dataTypeFactory, {});
|
|
48
|
-
|
|
49
|
-
const structureInfo = dataTypeFactory.getStructureInfoForDataType(dataTypeNodeId)!;
|
|
50
|
-
if (!structureInfo.constructor) {
|
|
51
|
-
throw new Error("Cannot find constructor for abstract DataType");
|
|
52
|
-
}
|
|
53
|
-
return structureInfo.constructor;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
12
|
export async function resolveOpaqueStructureInExtensionObject(
|
|
57
13
|
session: IBasicSessionAsync2,
|
|
58
14
|
dataTypeManager: ExtraDataTypeManager,
|
|
59
|
-
object: ExtensionObject
|
|
15
|
+
object: ExtensionObject,
|
|
16
|
+
visited?: Set<any>
|
|
60
17
|
): Promise<void> {
|
|
61
|
-
|
|
18
|
+
|
|
19
|
+
visited = visited || new Set();
|
|
20
|
+
if (visited.has(object)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
visited.add(object);
|
|
24
|
+
|
|
62
25
|
interface D {
|
|
63
26
|
dataTypeManager: ExtraDataTypeManager;
|
|
64
27
|
promises: Promise<void>[];
|
|
28
|
+
visited: Set<any>;
|
|
65
29
|
}
|
|
66
30
|
async function fixOpaqueStructureOnElement(
|
|
67
|
-
element:
|
|
31
|
+
element: any,
|
|
68
32
|
field: StructuredTypeField,
|
|
69
33
|
data: D,
|
|
70
34
|
args?: any
|
|
71
35
|
): Promise<unknown> {
|
|
72
|
-
|
|
73
|
-
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if (!element) {
|
|
74
39
|
return element;
|
|
75
40
|
}
|
|
76
|
-
|
|
41
|
+
|
|
42
|
+
if (element instanceof Variant || element.constructor?.name === "Variant") {
|
|
43
|
+
await resolveDynamicExtensionObject(session, element, dataTypeManager, data.visited);
|
|
77
44
|
return element;
|
|
78
45
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
46
|
+
if (element instanceof ExtensionObject || element?.constructor?.schema?.name === "ExtensionObject") {
|
|
47
|
+
if (element instanceof OpaqueStructure) {
|
|
48
|
+
const variant = new Variant({ dataType: DataType.ExtensionObject, value: element });
|
|
49
|
+
await resolveDynamicExtensionObject(session, variant, dataTypeManager, data.visited);
|
|
50
|
+
return variant.value as unknown;
|
|
51
|
+
} else {
|
|
52
|
+
await resolveOpaqueStructureInExtensionObject(session, dataTypeManager, element, data.visited);
|
|
53
|
+
return element;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return element;
|
|
82
57
|
}
|
|
83
58
|
function fixOpaqueStructure(object: any, field: StructuredTypeField, data: D, args?: any) {
|
|
84
|
-
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
if (field.category === "basic" && field.fieldType !== "Variant") {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
59
|
+
|
|
90
60
|
const a = object[field.name];
|
|
91
61
|
if (!a) {
|
|
92
62
|
return;
|
|
@@ -94,14 +64,14 @@ export async function resolveOpaqueStructureInExtensionObject(
|
|
|
94
64
|
if (field.isArray) {
|
|
95
65
|
for (let i = 0; i < a.length; i++) {
|
|
96
66
|
const x = a[i];
|
|
97
|
-
promises.push(
|
|
67
|
+
data.promises.push(
|
|
98
68
|
(async () => {
|
|
99
69
|
a[i] = await fixOpaqueStructureOnElement(x, field, data, args);
|
|
100
70
|
})()
|
|
101
71
|
);
|
|
102
72
|
}
|
|
103
73
|
} else {
|
|
104
|
-
promises.push(
|
|
74
|
+
data.promises.push(
|
|
105
75
|
(async () => {
|
|
106
76
|
object[field.name] = await fixOpaqueStructureOnElement(a, field, data, args);
|
|
107
77
|
})()
|
|
@@ -109,64 +79,63 @@ export async function resolveOpaqueStructureInExtensionObject(
|
|
|
109
79
|
}
|
|
110
80
|
}
|
|
111
81
|
const promises: Promise<void>[] = [];
|
|
112
|
-
object.applyOnAllFields<D>(fixOpaqueStructure, { dataTypeManager, promises });
|
|
82
|
+
object.applyOnAllFields<D>(fixOpaqueStructure, { dataTypeManager, promises, visited });
|
|
113
83
|
await Promise.all(promises);
|
|
114
84
|
}
|
|
115
85
|
|
|
116
|
-
async function resolveDynamicExtensionObjectV(
|
|
117
|
-
session: IBasicSessionAsync2,
|
|
118
|
-
opaque: OpaqueStructure,
|
|
119
|
-
dataTypeManager: ExtraDataTypeManager
|
|
120
|
-
): Promise<ExtensionObject> {
|
|
121
|
-
try {
|
|
122
|
-
const Constructor = await getOrExtractConstructor(session, opaque.nodeId, dataTypeManager);
|
|
123
|
-
const object = new Constructor();
|
|
124
|
-
const stream = new BinaryStream(opaque.buffer);
|
|
125
|
-
try {
|
|
126
|
-
object.decode(stream);
|
|
127
|
-
await resolveOpaqueStructureInExtensionObject(session, dataTypeManager, object);
|
|
128
|
-
return object;
|
|
129
|
-
} catch (err) {
|
|
130
|
-
warningLog("Constructor = ", Constructor.name);
|
|
131
|
-
warningLog("opaqueStructure = ", opaque?.nodeId?.toString());
|
|
132
|
-
warningLog("opaqueStructure = ", hexDump(opaque.buffer, 132, 100));
|
|
133
|
-
warningLog(hexDump(opaque.buffer));
|
|
134
|
-
warningLog("resolveDynamicExtensionObjectV err = ", err);
|
|
135
|
-
// try again for debugging
|
|
136
|
-
object.decode(stream);
|
|
137
|
-
return opaque;
|
|
138
|
-
}
|
|
139
|
-
} catch (err) {
|
|
140
|
-
warningLog("err", err);
|
|
141
|
-
warningLog("opaqueStructure = ", opaque.nodeId.toString());
|
|
142
|
-
warningLog("opaqueStructure = ", "0x" + hexDump(opaque.buffer, 132, 100));
|
|
143
|
-
warningLog(hexDump(opaque.buffer));
|
|
144
|
-
warningLog(dataTypeManager.toString());
|
|
145
|
-
throw err;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
86
|
export async function resolveDynamicExtensionObject(
|
|
150
87
|
session: IBasicSessionAsync2,
|
|
151
88
|
variant: Variant,
|
|
152
|
-
dataTypeManager: ExtraDataTypeManager
|
|
89
|
+
dataTypeManager: ExtraDataTypeManager,
|
|
90
|
+
visited?: Set<any>
|
|
153
91
|
): Promise<void> {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
92
|
+
visited = visited || new Set();
|
|
93
|
+
|
|
94
|
+
const handleValue = async (value: any): Promise<any> => {
|
|
95
|
+
if (!value) {
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
if (value instanceof OpaqueStructure) {
|
|
99
|
+
try {
|
|
100
|
+
const Constructor = await dataTypeManager.getExtensionObjectConstructorFromBinaryEncodingAsync(value.nodeId);
|
|
101
|
+
const object = new Constructor();
|
|
102
|
+
const stream = new BinaryStream(value.buffer);
|
|
103
|
+
try {
|
|
104
|
+
object.decode(stream);
|
|
105
|
+
await resolveOpaqueStructureInExtensionObject(session, dataTypeManager, object, visited!);
|
|
106
|
+
return object;
|
|
107
|
+
} catch (err) {
|
|
108
|
+
warningLog("resolveDynamicExtensionObjectV: error decoding or resolving inner structures");
|
|
109
|
+
warningLog("Constructor = ", Constructor.name);
|
|
110
|
+
warningLog("opaqueStructure = ", value?.nodeId?.toString());
|
|
111
|
+
warningLog("resolveDynamicExtensionObjectV err = ", (err as Error).message, (err as Error).stack);
|
|
112
|
+
return value;
|
|
162
113
|
}
|
|
114
|
+
} catch (err) {
|
|
115
|
+
warningLog("resolveDynamicExtensionObjectV: error getting constructor");
|
|
116
|
+
warningLog("opaqueStructure = ", value.nodeId.toString());
|
|
117
|
+
warningLog("err", (err as Error).message, (err as Error).stack);
|
|
118
|
+
return value;
|
|
163
119
|
}
|
|
164
120
|
}
|
|
165
|
-
|
|
121
|
+
if (value instanceof ExtensionObject) {
|
|
122
|
+
await resolveOpaqueStructureInExtensionObject(session, dataTypeManager, value, visited!);
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
if (value instanceof Variant) {
|
|
126
|
+
await resolveDynamicExtensionObject(session, value, dataTypeManager, visited!);
|
|
127
|
+
return value;
|
|
128
|
+
}
|
|
129
|
+
return value;
|
|
166
130
|
}
|
|
167
131
|
|
|
168
|
-
if (
|
|
169
|
-
|
|
132
|
+
if (variant.arrayType !== VariantArrayType.Scalar) {
|
|
133
|
+
if (Array.isArray(variant.value)) {
|
|
134
|
+
for (let i = 0; i < variant.value.length; i++) {
|
|
135
|
+
variant.value[i] = await handleValue(variant.value[i]);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
variant.value = await handleValue(variant.value);
|
|
170
140
|
}
|
|
171
|
-
variant.value = await resolveDynamicExtensionObjectV(session, variant.value, dataTypeManager);
|
|
172
141
|
}
|