node-opcua-client-dynamic-extension-object 2.51.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 (49) hide show
  1. package/LICENSE +20 -0
  2. package/dist/convert_data_type_definition_to_structuretype_schema.d.ts +12 -0
  3. package/dist/convert_data_type_definition_to_structuretype_schema.js +284 -0
  4. package/dist/convert_data_type_definition_to_structuretype_schema.js.map +1 -0
  5. package/dist/extra_data_type_manager.d.ts +16 -0
  6. package/dist/extra_data_type_manager.js +76 -0
  7. package/dist/extra_data_type_manager.js.map +1 -0
  8. package/dist/get_extension_object_constructor.d.ts +7 -0
  9. package/dist/get_extension_object_constructor.js +38 -0
  10. package/dist/get_extension_object_constructor.js.map +1 -0
  11. package/dist/get_extra_data_type_manager.d.ts +3 -0
  12. package/dist/get_extra_data_type_manager.js +52 -0
  13. package/dist/get_extra_data_type_manager.js.map +1 -0
  14. package/dist/index.d.ts +11 -0
  15. package/dist/index.js +24 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/populate_data_type_manager.d.ts +3 -0
  18. package/dist/populate_data_type_manager.js +26 -0
  19. package/dist/populate_data_type_manager.js.map +1 -0
  20. package/dist/private/convert_data_type_definition_to_structuretype_schema.d.ts +12 -0
  21. package/dist/private/convert_data_type_definition_to_structuretype_schema.js +284 -0
  22. package/dist/private/convert_data_type_definition_to_structuretype_schema.js.map +1 -0
  23. package/dist/private/find_encodings.d.ts +4 -0
  24. package/dist/private/find_encodings.js +56 -0
  25. package/dist/private/find_encodings.js.map +1 -0
  26. package/dist/private/populate_data_type_manager_103.d.ts +9 -0
  27. package/dist/private/populate_data_type_manager_103.js +599 -0
  28. package/dist/private/populate_data_type_manager_103.js.map +1 -0
  29. package/dist/private/populate_data_type_manager_104.d.ts +9 -0
  30. package/dist/private/populate_data_type_manager_104.js +146 -0
  31. package/dist/private/populate_data_type_manager_104.js.map +1 -0
  32. package/dist/promote_opaque_structure.d.ts +6 -0
  33. package/dist/promote_opaque_structure.js +42 -0
  34. package/dist/promote_opaque_structure.js.map +1 -0
  35. package/dist/resolve_dynamic_extension_object.d.ts +4 -0
  36. package/dist/resolve_dynamic_extension_object.js +106 -0
  37. package/dist/resolve_dynamic_extension_object.js.map +1 -0
  38. package/package.json +47 -0
  39. package/source/convert_data_type_definition_to_structuretype_schema.ts +326 -0
  40. package/source/extra_data_type_manager.ts +89 -0
  41. package/source/get_extension_object_constructor.ts +28 -0
  42. package/source/get_extra_data_type_manager.ts +43 -0
  43. package/source/index.ts +11 -0
  44. package/source/populate_data_type_manager.ts +14 -0
  45. package/source/private/find_encodings.ts +44 -0
  46. package/source/private/populate_data_type_manager_103.ts +715 -0
  47. package/source/private/populate_data_type_manager_104.ts +153 -0
  48. package/source/promote_opaque_structure.ts +42 -0
  49. package/source/resolve_dynamic_extension_object.ts +104 -0
@@ -0,0 +1,326 @@
1
+ import { assert } from "node-opcua-assert";
2
+ import { AttributeIds, BrowseDirection, makeResultMask, NodeClassMask } from "node-opcua-data-model";
3
+ import { DataValue } from "node-opcua-data-value";
4
+ import { make_debugLog } from "node-opcua-debug";
5
+ import { DataTypeFactory, EnumerationDefinitionSchema, FieldCategory, FieldInterfaceOptions, getBuildInType, StructuredTypeSchema, TypeDefinition } from "node-opcua-factory";
6
+ import { NodeId, makeExpandedNodeId, resolveNodeId } from "node-opcua-nodeid";
7
+ import { browseAll, BrowseDescriptionLike, IBasicSession } from "node-opcua-pseudo-session";
8
+ import { StatusCodes } from "node-opcua-status-code";
9
+ import { EnumDefinition, DataTypeDefinition, StructureDefinition, StructureType } from "node-opcua-types";
10
+ //
11
+ import { _findEncodings } from "./private/find_encodings";
12
+
13
+
14
+ const debugLog = make_debugLog(__filename);
15
+
16
+ async function findSuperType(session: IBasicSession, dataTypeNodeId: NodeId): Promise<NodeId> {
17
+ const nodeToBrowse3: BrowseDescriptionLike = {
18
+ browseDirection: BrowseDirection.Inverse,
19
+ includeSubtypes: false,
20
+ nodeClassMask: NodeClassMask.DataType,
21
+ nodeId: dataTypeNodeId,
22
+ referenceTypeId: resolveNodeId("HasSubtype"),
23
+ resultMask: makeResultMask("NodeId | ReferenceType | BrowseName | NodeClass")
24
+ };
25
+ const result3 = await browseAll(session, nodeToBrowse3);
26
+
27
+ /* istanbul ignore next */
28
+ if (result3.statusCode !== StatusCodes.Good) {
29
+ throw new Error("Cannot find superType for " + dataTypeNodeId.toString());
30
+ }
31
+ result3.references = result3.references || [];
32
+
33
+ /* istanbul ignore next */
34
+ if (result3.references.length !== 1) {
35
+ console.log(result3.toString());
36
+ throw new Error("Invalid dataType with more than one superType " + dataTypeNodeId.toString());
37
+ }
38
+ return result3.references[0].nodeId;
39
+ }
40
+ async function findDataTypeCategory(
41
+ session: IBasicSession,
42
+ cache: { [key: string]: CacheForFieldResolution },
43
+ dataTypeNodeId: NodeId
44
+ ): Promise<FieldCategory> {
45
+ const subTypeNodeId = await findSuperType(session, dataTypeNodeId);
46
+ debugLog("subTypeNodeId of ", dataTypeNodeId.toString(), " is ", subTypeNodeId.toString());
47
+ const key = subTypeNodeId.toString();
48
+ if (cache[key]) {
49
+ return cache[key].category;
50
+ }
51
+ let category: FieldCategory;
52
+ if (subTypeNodeId.namespace === 0 && subTypeNodeId.value <= 29) {
53
+ // well known node ID !
54
+ switch (subTypeNodeId.value) {
55
+ case 22 /* Structure */:
56
+ category = FieldCategory.complex;
57
+ break;
58
+ case 29 /* Enumeration */:
59
+ category = FieldCategory.enumeration;
60
+ break;
61
+ default:
62
+ category = FieldCategory.basic;
63
+ break;
64
+ }
65
+ return category;
66
+ }
67
+ // must drill down ...
68
+ return await findDataTypeCategory(session, cache, subTypeNodeId);
69
+ }
70
+
71
+ async function findDataTypeBasicType(
72
+ session: IBasicSession,
73
+ cache: { [key: string]: CacheForFieldResolution },
74
+ dataTypeNodeId: NodeId
75
+ ): Promise<TypeDefinition> {
76
+ const subTypeNodeId = await findSuperType(session, dataTypeNodeId);
77
+
78
+ debugLog("subTypeNodeId of ", dataTypeNodeId.toString(), " is ", subTypeNodeId.toString());
79
+
80
+ const key = subTypeNodeId.toString();
81
+ if (cache[key]) {
82
+ return cache[key].schema;
83
+ }
84
+ if (subTypeNodeId.namespace === 0 && subTypeNodeId.value < 29) {
85
+ switch (subTypeNodeId.value) {
86
+ case 22: /* Structure */
87
+ case 29 /* Enumeration */:
88
+ throw new Error("Not expecting Structure or Enumeration");
89
+ default:
90
+ break;
91
+ }
92
+ const nameDataValue: DataValue = await session.read({
93
+ attributeId: AttributeIds.BrowseName,
94
+ nodeId: subTypeNodeId
95
+ });
96
+ const name = nameDataValue.value.value.name!;
97
+ return getBuildInType(name);
98
+ }
99
+ // must drill down ...
100
+ return await findDataTypeBasicType(session, cache, subTypeNodeId);
101
+ }
102
+
103
+
104
+ export interface CacheForFieldResolution {
105
+ fieldTypeName: string;
106
+ schema: TypeDefinition;
107
+ category: FieldCategory;
108
+ }
109
+
110
+ async function readBrowseName(session: IBasicSession, nodeId: NodeId): Promise<string> {
111
+ const dataValue = await session.read({ nodeId, attributeId: AttributeIds.BrowseName });
112
+ if (dataValue.statusCode !== StatusCodes.Good) {
113
+ const message =
114
+ "cannot extract BrowseName of nodeId = " + nodeId.toString() + " statusCode = " + dataValue.statusCode.toString();
115
+ debugLog(message);
116
+ throw new Error(message);
117
+ }
118
+ return dataValue.value!.value.name;
119
+ }
120
+
121
+ async function resolveFieldType(
122
+ session: IBasicSession,
123
+ dataTypeNodeId: NodeId,
124
+ dataTypeFactory: DataTypeFactory,
125
+ cache: { [key: string]: CacheForFieldResolution }
126
+ ): Promise<CacheForFieldResolution | null> {
127
+ if (dataTypeNodeId.namespace === 0 && dataTypeNodeId.value === 22) {
128
+ return null;
129
+ }
130
+ const key = dataTypeNodeId.toString();
131
+ const v = cache[key];
132
+ if (v) {
133
+ return v;
134
+ }
135
+
136
+ if (dataTypeNodeId.value === 0) {
137
+ const v3: CacheForFieldResolution = {
138
+ category: FieldCategory.basic,
139
+ fieldTypeName: "Variant",
140
+ schema: dataTypeFactory.getSimpleType("Variant")
141
+ };
142
+ cache[key] = v3;
143
+ return v3;
144
+ }
145
+
146
+ const fieldTypeName = await readBrowseName(session, dataTypeNodeId);
147
+
148
+ let schema: TypeDefinition | undefined;
149
+ let category: FieldCategory = FieldCategory.enumeration;
150
+
151
+ if (dataTypeFactory.hasStructuredType(fieldTypeName!)) {
152
+ schema = dataTypeFactory.getStructuredTypeSchema(fieldTypeName);
153
+ category = FieldCategory.complex;
154
+ } else if (dataTypeFactory.hasSimpleType(fieldTypeName!)) {
155
+ category = FieldCategory.basic;
156
+ schema = dataTypeFactory.getSimpleType(fieldTypeName!);
157
+ } else if (dataTypeFactory.hasEnumeration(fieldTypeName!)) {
158
+ category = FieldCategory.enumeration;
159
+ schema = dataTypeFactory.getEnumeration(fieldTypeName!)!;
160
+ } else {
161
+ debugLog(" type " + fieldTypeName + " has not been seen yet, let resolve it");
162
+ category = await findDataTypeCategory(session, cache, dataTypeNodeId);
163
+ debugLog(" type " + fieldTypeName + " has not been seen yet, let resolve it => (category = ", category, " )");
164
+
165
+ switch (category) {
166
+ case FieldCategory.basic:
167
+ schema = await findDataTypeBasicType(session, cache, dataTypeNodeId);
168
+ /* istanbul ignore next */
169
+ if (!schema) {
170
+ console.log("Cannot find basic type " + fieldTypeName);
171
+ }
172
+ break;
173
+ default:
174
+ case FieldCategory.enumeration:
175
+ case FieldCategory.complex:
176
+ const dataTypeDefinitionDataValue = await session.read({
177
+ attributeId: AttributeIds.DataTypeDefinition,
178
+ nodeId: dataTypeNodeId
179
+ });
180
+
181
+ /* istanbul ignore next */
182
+ if (dataTypeDefinitionDataValue.statusCode !== StatusCodes.Good) {
183
+ throw new Error(" Cannot find dataType Definition ! with nodeId =" + dataTypeNodeId.toString());
184
+ }
185
+ const definition = dataTypeDefinitionDataValue.value.value;
186
+
187
+ if (category === FieldCategory.enumeration) {
188
+ if (definition instanceof EnumDefinition) {
189
+ const e = new EnumerationDefinitionSchema({
190
+ enumValues: definition.fields,
191
+ name: fieldTypeName
192
+ });
193
+ dataTypeFactory.registerEnumeration(e);
194
+
195
+ schema = e;
196
+ }
197
+ } else {
198
+ schema = await convertDataTypeDefinitionToStructureTypeSchema(
199
+ session,
200
+ dataTypeNodeId,
201
+ fieldTypeName,
202
+ definition,
203
+ dataTypeFactory,
204
+ cache
205
+ );
206
+ }
207
+ // xx const schema1 = dataTypeFactory.getStructuredTypeSchema(fieldTypeName);
208
+ break;
209
+ }
210
+ }
211
+
212
+ /* istanbul ignore next */
213
+ if (!schema) {
214
+ throw new Error(
215
+ "expecting a schema here fieldTypeName=" + fieldTypeName + " " + dataTypeNodeId.toString() + " category = " + category
216
+ );
217
+ }
218
+
219
+ const v2: CacheForFieldResolution = {
220
+ category,
221
+ fieldTypeName,
222
+ schema
223
+ };
224
+ cache[key] = v2;
225
+ return v2;
226
+ }
227
+
228
+ async function _setupEncodings(
229
+ session: IBasicSession,
230
+ dataTypeNodeId: NodeId,
231
+ schema: StructuredTypeSchema
232
+ ): Promise<StructuredTypeSchema> {
233
+ // read abstract flag
234
+ const isAbstractDV = await session.read({ nodeId: dataTypeNodeId, attributeId: AttributeIds.IsAbstract });
235
+ schema.dataTypeNodeId = dataTypeNodeId;
236
+ schema.id = dataTypeNodeId;
237
+
238
+ if (isAbstractDV.statusCode === StatusCodes.Good && isAbstractDV.value.value === false) {
239
+ const encodings = await _findEncodings(session, dataTypeNodeId);
240
+ schema.encodingDefaultBinary = makeExpandedNodeId(encodings.binaryEncodingNodeId);
241
+ schema.encodingDefaultXml = makeExpandedNodeId(encodings.xmlEncodingNodeId);
242
+ schema.encodingDefaultJson = makeExpandedNodeId(encodings.jsonEncodingNodeId);
243
+ }
244
+ return schema;
245
+ }
246
+
247
+ export async function convertDataTypeDefinitionToStructureTypeSchema(
248
+ session: IBasicSession,
249
+ dataTypeNodeId: NodeId,
250
+ name: string,
251
+ definition: DataTypeDefinition,
252
+ dataTypeFactory: DataTypeFactory,
253
+ cache: { [key: string]: CacheForFieldResolution }
254
+ ): Promise<StructuredTypeSchema> {
255
+ if (definition instanceof StructureDefinition) {
256
+ const fields: FieldInterfaceOptions[] = [];
257
+
258
+ const isUnion = definition.structureType === StructureType.Union;
259
+
260
+ switch (definition.structureType) {
261
+ case StructureType.Union:
262
+ // xx console.log("Union Found : ", name);
263
+ fields.push({
264
+ fieldType: "UInt32",
265
+ name: "SwitchField"
266
+ });
267
+ break;
268
+ case StructureType.Structure:
269
+ case StructureType.StructureWithOptionalFields:
270
+ break;
271
+ }
272
+
273
+ let switchValue = 1;
274
+ let switchBit = 0;
275
+
276
+ const bitFields: { name: string; length?: number }[] | undefined = isUnion ? undefined : [];
277
+
278
+ for (const fieldD of definition.fields!) {
279
+ const rt = (await resolveFieldType(session, fieldD.dataType, dataTypeFactory, cache))!;
280
+ if (!rt) {
281
+ console.log("convertDataTypeDefinitionToStructureTypeSchema cannot handle field", fieldD.name, "in", name);
282
+ continue;
283
+ }
284
+ const { schema, category, fieldTypeName } = rt;
285
+
286
+ const field: FieldInterfaceOptions = {
287
+ fieldType: fieldTypeName!,
288
+ name: fieldD.name!,
289
+ schema
290
+ };
291
+
292
+ if (fieldD.isOptional) {
293
+ field.switchBit = switchBit++;
294
+ bitFields?.push({ name: fieldD.name! + "Specified", length: 1 });
295
+ }
296
+ if (isUnion) {
297
+ field.switchValue = switchValue;
298
+ switchValue += 1;
299
+ }
300
+
301
+ assert(fieldD.valueRank === -1 || fieldD.valueRank === 1 || fieldD.valueRank === 0);
302
+ if (fieldD.valueRank === 1) {
303
+ field.isArray = true;
304
+ } else {
305
+ field.isArray = false;
306
+ }
307
+ field.category = category;
308
+ field.schema = schema;
309
+ fields.push(field);
310
+ }
311
+
312
+ const a = await resolveFieldType(session, definition.baseDataType, dataTypeFactory, cache);
313
+ const baseType = a ? a.fieldTypeName : "ExtensionObject";
314
+
315
+ const os = new StructuredTypeSchema({
316
+ baseType,
317
+ bitFields,
318
+ fields,
319
+ id: 0,
320
+ name
321
+ });
322
+ const structuredTypeSchema = await _setupEncodings(session, dataTypeNodeId, os);
323
+ return structuredTypeSchema;
324
+ }
325
+ throw new Error("Not Implemented");
326
+ }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * @module node-opcua-client-dynamic-extension-object
3
+ */
4
+ import { format } from "util";
5
+
6
+ import { assert } from "node-opcua-assert";
7
+ import {
8
+ ConstructorFunc,
9
+ DataTypeFactory,
10
+ getStandardDataTypeFactory
11
+ } from "node-opcua-factory";
12
+ import { NodeId } from "node-opcua-nodeid";
13
+ import { AnyConstructorFunc } from "node-opcua-schemas";
14
+
15
+ export class ExtraDataTypeManager {
16
+ public namespaceArray: string[] = [];
17
+
18
+ private readonly dataTypeFactoryMapByNamespace: { [key: number]: DataTypeFactory } = {};
19
+
20
+ constructor() {
21
+ /* */
22
+ }
23
+
24
+ public setNamespaceArray(namespaceArray: string[]): void {
25
+ this.namespaceArray = namespaceArray;
26
+ }
27
+
28
+ public hasDataTypeFactory(namespaceIndex: number): boolean {
29
+ return !!Object.prototype.hasOwnProperty.call(this.dataTypeFactoryMapByNamespace,namespaceIndex);
30
+ }
31
+
32
+ public registerDataTypeFactory(namespaceIndex: number, dataTypeFactory: DataTypeFactory): void {
33
+ /* istanbul ignore next */
34
+ assert(namespaceIndex !== 0, "registerTypeDictionary cannot be used for namespace 0");
35
+ if (this.hasDataTypeFactory(namespaceIndex)) {
36
+ throw new Error("Dictionary already registered");
37
+ }
38
+ this.dataTypeFactoryMapByNamespace[namespaceIndex] = dataTypeFactory;
39
+ }
40
+
41
+ public getDataTypeFactoryForNamespace(namespaceIndex: number): DataTypeFactory {
42
+ assert(namespaceIndex !== 0, "getTypeDictionaryForNamespace cannot be used for namespace 0");
43
+ return this.dataTypeFactoryMapByNamespace[namespaceIndex];
44
+ }
45
+ public getDataTypeFactory(namespaceIndex: number): DataTypeFactory {
46
+ if (namespaceIndex === 0) {
47
+ return getStandardDataTypeFactory();
48
+ }
49
+ return this.dataTypeFactoryMapByNamespace[namespaceIndex];
50
+ }
51
+
52
+ public getExtensionObjectConstructorFromDataType(dataTypeNodeId: NodeId): AnyConstructorFunc {
53
+ const dataTypeFactory = this.getDataTypeFactory(dataTypeNodeId.namespace);
54
+ if (!dataTypeFactory) {
55
+ throw new Error("cannot find dataFactory for namespace=" + dataTypeNodeId.namespace);
56
+ }
57
+ // find schema corresponding to dataTypeNodeId in typeDictionary
58
+ const Constructor = dataTypeFactory.findConstructorForDataType(dataTypeNodeId);
59
+ return Constructor;
60
+ }
61
+
62
+ public getExtensionObjectConstructorFromBinaryEncoding(binaryEncodingNodeId: NodeId): ConstructorFunc {
63
+ const dataTypeFactory = this.getDataTypeFactoryForNamespace(binaryEncodingNodeId.namespace);
64
+ const Constructor = dataTypeFactory.getConstructor(binaryEncodingNodeId);
65
+ if (!Constructor) {
66
+ throw new Error(
67
+ "getExtensionObjectConstructorFromBinaryEncoding cannot find constructor for binaryEncoding " +
68
+ binaryEncodingNodeId.toString()
69
+ );
70
+ }
71
+ return Constructor;
72
+ }
73
+ public toString(): string {
74
+ const l: string[] = [];
75
+ function write(...args: [any, ...any[]]) {
76
+ l.push(format.apply(format, args));
77
+ }
78
+ write("ExtraDataTypeManager");
79
+ for (let n = 0; n < this.namespaceArray.length; n++) {
80
+ write("------------- namespace:", this.namespaceArray[n]);
81
+ const dataFactory = this.dataTypeFactoryMapByNamespace[n];
82
+ if (!dataFactory) {
83
+ continue;
84
+ }
85
+ write(dataFactory.toString());
86
+ }
87
+ return l.join("\n");
88
+ }
89
+ }
@@ -0,0 +1,28 @@
1
+ import { QualifiedName, AttributeIds } from "node-opcua-data-model";
2
+ import { NodeId } from "node-opcua-nodeid";
3
+ import { IBasicSession } from "node-opcua-pseudo-session";
4
+ import { AnyConstructorFunc } from "node-opcua-schemas";
5
+ //
6
+ import { getExtraDataTypeManager } from "./get_extra_data_type_manager";
7
+ import { readDataTypeDefinitionAndBuildType } from "./private/populate_data_type_manager_104";
8
+
9
+ /**
10
+ *
11
+ */
12
+ export async function getExtensionObjectConstructor(session: IBasicSession, dataTypeNodeId: NodeId): Promise<AnyConstructorFunc> {
13
+ const extraDataTypeManager = await getExtraDataTypeManager(session);
14
+
15
+ const dataTypeFactory = extraDataTypeManager.getDataTypeFactory(dataTypeNodeId.namespace);
16
+ const Constructor = dataTypeFactory.getConstructorForDataType(dataTypeNodeId);
17
+ if (Constructor) {
18
+ return Constructor;
19
+ }
20
+ const dataValue = await session.read({
21
+ nodeId: dataTypeNodeId,
22
+ attributeId: AttributeIds.BrowseName
23
+ });
24
+ const browseName = dataValue.value.value as QualifiedName;
25
+ await readDataTypeDefinitionAndBuildType(session, dataTypeNodeId, browseName.name!, dataTypeFactory, {});
26
+
27
+ return await extraDataTypeManager.getExtensionObjectConstructorFromDataType(dataTypeNodeId);
28
+ }
@@ -0,0 +1,43 @@
1
+ import { checkDebugFlag, make_debugLog, make_errorLog } from "node-opcua-debug";
2
+ import { DataTypeFactory, getStandardDataTypeFactory } from "node-opcua-factory";
3
+ import { IBasicSession, readNamespaceArray } from "node-opcua-pseudo-session";
4
+ //
5
+ import { ExtraDataTypeManager } from "./extra_data_type_manager";
6
+ import { populateDataTypeManager } from "./populate_data_type_manager";
7
+
8
+ const doDebug = checkDebugFlag(__filename);
9
+ const debugLog = make_debugLog(__filename);
10
+ const errorLog = make_errorLog(__filename);
11
+
12
+ interface IBasicSessionEx extends IBasicSession {
13
+ $$extraDataTypeManager?: ExtraDataTypeManager;
14
+ }
15
+
16
+ export async function getExtraDataTypeManager(session: IBasicSession): Promise<ExtraDataTypeManager> {
17
+ const sessionPriv: IBasicSessionEx = session as IBasicSessionEx;
18
+ if (!sessionPriv.$$extraDataTypeManager) {
19
+ const dataTypeManager = new ExtraDataTypeManager();
20
+
21
+ const namespaceArray = await readNamespaceArray(sessionPriv);
22
+ // istanbul ignore next
23
+ if (namespaceArray.length === 0) {
24
+ errorLog("namespaceArray is not populated ! Your server must expose a list of namespace ");
25
+ }
26
+ // istanbul ignore next
27
+ if (doDebug) {
28
+ debugLog("Namespace Array = ", namespaceArray.join("\n "));
29
+ }
30
+ sessionPriv.$$extraDataTypeManager = dataTypeManager;
31
+ dataTypeManager.setNamespaceArray(namespaceArray);
32
+ for (let namespaceIndex = 1; namespaceIndex < namespaceArray.length; namespaceIndex++) {
33
+ const dataTypeFactory1 = new DataTypeFactory([getStandardDataTypeFactory()]);
34
+ dataTypeManager.registerDataTypeFactory(namespaceIndex, dataTypeFactory1);
35
+ }
36
+ await populateDataTypeManager(session, dataTypeManager, false);
37
+ }
38
+ // istanbul ignore next
39
+ if (sessionPriv.$$extraDataTypeManager.namespaceArray.length === 0) {
40
+ throw new Error("namespaceArray is not populated ! Your server must expose a list of namespace ");
41
+ }
42
+ return sessionPriv.$$extraDataTypeManager;
43
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @module node-opcua-client-dynamic-extension-object
3
+ */
4
+ export * from "./populate_data_type_manager";
5
+ export * from "./extra_data_type_manager";
6
+ export * from "./resolve_dynamic_extension_object";
7
+ export * from "./promote_opaque_structure";
8
+ export * from "./get_extension_object_constructor";
9
+ export * from "./get_extra_data_type_manager";
10
+ export * from "./resolve_dynamic_extension_object";
11
+ export * from "./convert_data_type_definition_to_structuretype_schema";
@@ -0,0 +1,14 @@
1
+ import { IBasicSession } from "node-opcua-pseudo-session";
2
+ //
3
+ import { ExtraDataTypeManager } from "./extra_data_type_manager";
4
+ import { populateDataTypeManager103 } from "./private/populate_data_type_manager_103";
5
+ import { populateDataTypeManager104 } from "./private/populate_data_type_manager_104";
6
+
7
+ export async function populateDataTypeManager(session: IBasicSession, dataTypeManager: ExtraDataTypeManager, force: boolean ): Promise<void> {
8
+ // old way for 1.03 and early 1.04 prototype
9
+ await populateDataTypeManager103(session, dataTypeManager);
10
+ // new way for 1.04 and later
11
+ if (force) {
12
+ await populateDataTypeManager104(session, dataTypeManager);
13
+ }
14
+ }
@@ -0,0 +1,44 @@
1
+ import { BrowseDirection, makeNodeClassMask, makeResultMask } from "node-opcua-data-model";
2
+ import { NodeId, resolveNodeId } from "node-opcua-nodeid";
3
+ import { IBasicSession, BrowseDescriptionLike, browseAll } from "node-opcua-pseudo-session";
4
+ import { DataTypeAndEncodingId } from "node-opcua-schemas";
5
+
6
+
7
+ export async function _findEncodings(session: IBasicSession, dataTypeNodeId: NodeId): Promise<DataTypeAndEncodingId> {
8
+ const nodeToBrowse: BrowseDescriptionLike = {
9
+ browseDirection: BrowseDirection.Forward,
10
+ includeSubtypes: true,
11
+ nodeClassMask: makeNodeClassMask("Object"),
12
+ nodeId: dataTypeNodeId,
13
+ referenceTypeId: resolveNodeId("HasEncoding"),
14
+ resultMask: makeResultMask("ReferenceType | IsForward | BrowseName | NodeClass | TypeDefinition")
15
+ };
16
+ const result = await browseAll(session, nodeToBrowse);
17
+ const references = result.references || [];
18
+ if (references.length === 0) {
19
+ // xx throw new Error("Cannot find encodings on type " + dataTypeNodeId.toString() + " statusCode " + result.statusCode.toString());
20
+ }
21
+ const encodings: DataTypeAndEncodingId = {
22
+ dataTypeNodeId,
23
+
24
+ binaryEncodingNodeId: NodeId.nullNodeId,
25
+ jsonEncodingNodeId: NodeId.nullNodeId,
26
+ xmlEncodingNodeId: NodeId.nullNodeId
27
+ };
28
+ for (const ref of references) {
29
+ switch (ref.browseName.name) {
30
+ case "Default Binary":
31
+ encodings.binaryEncodingNodeId = ref.nodeId;
32
+ break;
33
+ case "Default XML":
34
+ encodings.xmlEncodingNodeId = ref.nodeId;
35
+ break;
36
+ case "Default JSON":
37
+ encodings.jsonEncodingNodeId = ref.nodeId;
38
+ break;
39
+ default:
40
+ console.log(" ignoring encoding ", ref.browseName.toString());
41
+ }
42
+ }
43
+ return encodings;
44
+ }