node-opcua-schemas 2.76.0 → 2.76.2

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.
@@ -1,691 +1,691 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createDynamicObjectConstructor = exports.DynamicExtensionObject = exports.getOrCreateConstructor = void 0;
4
- /**
5
- * @module node-opcua-schemas
6
- */
7
- const node_opcua_assert_1 = require("node-opcua-assert");
8
- const node_opcua_debug_1 = require("node-opcua-debug");
9
- const node_opcua_extension_object_1 = require("node-opcua-extension-object");
10
- const node_opcua_variant_1 = require("node-opcua-variant");
11
- const node_opcua_factory_1 = require("node-opcua-factory");
12
- const node_opcua_nodeid_1 = require("node-opcua-nodeid");
13
- const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
14
- const errorLog = (0, node_opcua_debug_1.make_errorLog)(__filename);
15
- const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
16
- function getOrCreateConstructor(dataTypeName, dataTypeFactory, encodingDefaultBinary, encodingDefaultXml) {
17
- if (dataTypeFactory.hasStructuredType(dataTypeName)) {
18
- return dataTypeFactory.getStructureTypeConstructor(dataTypeName);
19
- }
20
- const schema = dataTypeFactory.getStructuredTypeSchema(dataTypeName);
21
- // istanbul ignore next
22
- if (!schema) {
23
- throw new Error("Unknown type in dictionary " + dataTypeName);
24
- }
25
- const constructor = createDynamicObjectConstructor(schema, dataTypeFactory);
26
- if (!constructor) {
27
- return constructor;
28
- }
29
- // istanbul ignore next
30
- if (!dataTypeFactory.hasStructuredType(dataTypeName)) {
31
- dataTypeFactory.registerClassDefinition(schema.id, dataTypeName, constructor);
32
- return constructor;
33
- // hrow new Error("constructor should now be registered - " + fieldType);
34
- }
35
- if (encodingDefaultBinary && encodingDefaultBinary.value !== 0) {
36
- schema.encodingDefaultBinary = encodingDefaultBinary;
37
- schema.encodingDefaultXml = encodingDefaultXml;
38
- constructor.encodingDefaultBinary = encodingDefaultBinary;
39
- constructor.encodingDefaultXml = encodingDefaultXml;
40
- dataTypeFactory.associateWithBinaryEncoding(dataTypeName, encodingDefaultBinary);
41
- }
42
- return constructor;
43
- }
44
- exports.getOrCreateConstructor = getOrCreateConstructor;
45
- function encodeElement(field, element, stream, encodeFunc) {
46
- if (encodeFunc) {
47
- encodeFunc(element, stream);
48
- }
49
- else {
50
- // istanbul ignore next
51
- if (!element.encode) {
52
- throw new Error("encodeArrayOrElement: object field " + field.name + " has no encode method and encodeFunc is missing");
53
- }
54
- if (field.allowSubType) {
55
- (0, node_opcua_extension_object_1.encodeExtensionObject)(element, stream);
56
- // new Variant({ dataType: DataType.ExtensionObject, value: element }).encode(stream);
57
- }
58
- else {
59
- element.encode(stream);
60
- }
61
- }
62
- }
63
- function encodeArrayOrElement(field, obj, stream, encodeFunc) {
64
- if (field.isArray) {
65
- const array = obj[field.name];
66
- if (!array) {
67
- stream.writeUInt32(0xffffffff);
68
- }
69
- else {
70
- stream.writeUInt32(array.length);
71
- for (const e of array) {
72
- encodeElement(field, e, stream, encodeFunc);
73
- }
74
- }
75
- }
76
- else {
77
- encodeElement(field, obj[field.name], stream, encodeFunc);
78
- }
79
- }
80
- function decodeElement(factory, field, stream, decodeFunc) {
81
- if (decodeFunc) {
82
- return decodeFunc(stream);
83
- }
84
- else {
85
- if (field.allowSubType) {
86
- const element = (0, node_opcua_extension_object_1.decodeExtensionObject)(stream);
87
- return element;
88
- }
89
- else {
90
- // construct an instance
91
- const constructor = factory.getStructureTypeConstructor(field.fieldType);
92
- const element = new constructor({});
93
- element.decode(stream);
94
- return element;
95
- }
96
- }
97
- }
98
- function decodeArrayOrElement(factory, field, obj, stream, decodeFunc) {
99
- if (field.isArray) {
100
- const array = [];
101
- const nbElements = stream.readUInt32();
102
- if (nbElements === 0xffffffff) {
103
- obj[field.name] = null;
104
- }
105
- else {
106
- for (let i = 0; i < nbElements; i++) {
107
- const element = decodeElement(factory, field, stream, decodeFunc);
108
- array.push(element);
109
- }
110
- obj[field.name] = array;
111
- }
112
- }
113
- else {
114
- obj[field.name] = decodeElement(factory, field, stream, decodeFunc);
115
- }
116
- }
117
- function isSubtype(factory, dataTypeNodeId, schema) {
118
- var _a;
119
- if (dataTypeNodeId.toString() === schema.dataTypeNodeId.toString()) {
120
- return true;
121
- }
122
- if (!schema._baseSchema || !((_a = schema._baseSchema) === null || _a === void 0 ? void 0 : _a.dataTypeNodeId))
123
- return false;
124
- const c = factory.getConstructorForDataType(schema._baseSchema.dataTypeNodeId);
125
- if (!c) {
126
- return false;
127
- }
128
- return isSubtype(factory, dataTypeNodeId, c.schema);
129
- }
130
- function _validateSubType(factory, field, value) {
131
- (0, node_opcua_assert_1.assert)(field.allowSubType);
132
- if (!value) {
133
- value = { dataType: node_opcua_variant_1.DataType.Null, value: null };
134
- // const msg = "initializeField: field { dataType,value} is required here";
135
- // errorLog(msg);
136
- // throw new Error(msg);
137
- return;
138
- }
139
- if (field.category === "basic") {
140
- if (!Object.prototype.hasOwnProperty.call(value, "dataType")) {
141
- const msg = "initializeField: field that allow subtype must be a Variant like and have a dataType property";
142
- errorLog(msg);
143
- throw new Error(msg);
144
- }
145
- const c = factory.getBuiltInTypeByDataType((0, node_opcua_nodeid_1.coerceNodeId)(`i=${value.dataType}`, 0));
146
- const d = factory.getBuiltInType(field.fieldType);
147
- if (c && c.isSubTypeOf(d)) {
148
- return;
149
- }
150
- const msg = "initializeField: invalid subtype for field " +
151
- field.name +
152
- " expecting " +
153
- field.fieldType +
154
- " but got " +
155
- node_opcua_variant_1.DataType[value.dataType];
156
- errorLog(msg);
157
- throw new Error(msg);
158
- }
159
- else {
160
- if (value !== null && !(value instanceof node_opcua_extension_object_1.ExtensionObject)) {
161
- errorLog("initializeField: array element is not an ExtensionObject");
162
- throw new Error(`${field.name}: array element must be an ExtensionObject`);
163
- }
164
- const e = value;
165
- if (!isSubtype(factory, field.dataType, e.schema)) {
166
- const msg = "initializeField: invalid subtype for field " +
167
- field.name +
168
- " expecting " +
169
- field.fieldType +
170
- " but got " +
171
- e.schema.id.toString() +
172
- " " +
173
- e.schema.name;
174
- errorLog(msg);
175
- throw new Error(msg);
176
- }
177
- }
178
- }
179
- function validateSubTypeA(factory, field, value) {
180
- if (field.isArray) {
181
- const arr = value || [];
182
- for (const e of arr) {
183
- // now check that element is of the correct type
184
- _validateSubType(factory, field, e);
185
- }
186
- }
187
- else {
188
- _validateSubType(factory, field, value);
189
- }
190
- }
191
- function initializeField(field, thisAny, options, schema, factory) {
192
- const name = field.name;
193
- const value = getFieldValue(field, options);
194
- switch (field.category) {
195
- case node_opcua_factory_1.FieldCategory.complex: {
196
- if (field.allowSubType) {
197
- validateSubTypeA(factory, field, value);
198
- if (field.isArray) {
199
- const arr = value || [];
200
- thisAny[name] = arr.map((x) => x.clone());
201
- }
202
- else {
203
- const e = value;
204
- if (e !== null && !(e instanceof node_opcua_extension_object_1.ExtensionObject)) {
205
- errorLog("initializeField: array element is not an ExtensionObject");
206
- }
207
- // now check that element is of the correct type
208
- thisAny[name] = e.clone();
209
- }
210
- }
211
- else {
212
- const constructor = factory.getStructureTypeConstructor(field.fieldType);
213
- if (field.isArray) {
214
- const arr = value || [];
215
- thisAny[name] = arr.map((x) => (constructor ? new constructor(x) : null));
216
- }
217
- else {
218
- thisAny[name] = constructor ? new constructor(value) : null;
219
- }
220
- }
221
- // getOrCreateConstructor(field.fieldType, factory) || BaseUAObject;
222
- // xx processStructuredType(fieldSchema);
223
- break;
224
- }
225
- case node_opcua_factory_1.FieldCategory.enumeration:
226
- case node_opcua_factory_1.FieldCategory.basic:
227
- if (field.allowSubType) {
228
- validateSubTypeA(factory, field, value);
229
- }
230
- if (field.isArray) {
231
- thisAny[name] = (0, node_opcua_factory_1.initialize_field_array)(field, value, factory);
232
- }
233
- else {
234
- thisAny[name] = (0, node_opcua_factory_1.initialize_field)(field, value, factory);
235
- }
236
- break;
237
- }
238
- }
239
- function getFieldValue(field, options) {
240
- return options[field.name] !== undefined ? options[field.name] : options[field.originalName];
241
- }
242
- function initializeFields(thisAny, options, schema, factory, params) {
243
- // initialize base class first
244
- if (schema._baseSchema && schema._baseSchema.fields.length) {
245
- initializeFields(thisAny, options, schema._baseSchema, factory, params);
246
- }
247
- // finding fields that are in options but not in schema!
248
- for (const field of schema.fields) {
249
- const name = field.name;
250
- const value = getFieldValue(field, options);
251
- // dealing with optional fields
252
- if (field.switchBit !== undefined && value === undefined) {
253
- thisAny[name] = undefined;
254
- continue;
255
- }
256
- initializeField(field, thisAny, options, schema, factory);
257
- }
258
- }
259
- function hasOptionalFieldsF(schema) {
260
- if (schema.bitFields && schema.bitFields.length > 0) {
261
- return true;
262
- }
263
- return schema._baseSchema ? hasOptionalFieldsF(schema._baseSchema) : false;
264
- }
265
- function _internal_encodeFields(thisAny, schema, stream) {
266
- // encodeFields base class first
267
- if (schema._baseSchema && schema._baseSchema.fields.length) {
268
- _internal_encodeFields(thisAny, schema._baseSchema, stream);
269
- }
270
- for (const field of schema.fields) {
271
- // ignore
272
- if (field.switchBit !== undefined && thisAny[field.name] === undefined) {
273
- continue;
274
- }
275
- switch (field.category) {
276
- case node_opcua_factory_1.FieldCategory.complex:
277
- encodeArrayOrElement(field, thisAny, stream);
278
- break;
279
- case node_opcua_factory_1.FieldCategory.enumeration:
280
- case node_opcua_factory_1.FieldCategory.basic:
281
- encodeArrayOrElement(field, thisAny, stream, field.schema.encode);
282
- break;
283
- default:
284
- /* istanbul ignore next*/
285
- throw new Error("Invalid category " + field.category + " " + node_opcua_factory_1.FieldCategory[field.category]);
286
- }
287
- }
288
- }
289
- function makeBitField(thisAny, schema, bo) {
290
- const data = schema._baseSchema ? makeBitField(thisAny, schema._baseSchema, bo) : bo;
291
- let { bitField, allOptional } = data;
292
- const { offset } = data;
293
- let nbOptionalFields = 0;
294
- for (const field of schema.fields) {
295
- if (field.switchBit === undefined) {
296
- allOptional = false;
297
- continue;
298
- }
299
- nbOptionalFields += 1;
300
- if (thisAny[field.name] === undefined) {
301
- continue;
302
- }
303
- // tslint:disable-next-line:no-bitwise
304
- bitField |= 1 << (field.switchBit + offset);
305
- }
306
- return { bitField, offset: nbOptionalFields + offset, allOptional };
307
- }
308
- function encodeFields(thisAny, schema, stream) {
309
- const hasOptionalFields = hasOptionalFieldsF(schema);
310
- // ============ Deal with switchBits
311
- if (hasOptionalFields) {
312
- const { bitField, allOptional } = makeBitField(thisAny, schema, { bitField: 0, offset: 0, allOptional: true });
313
- if (!(bitField === 0 && allOptional)) {
314
- stream.writeUInt32(bitField);
315
- }
316
- }
317
- _internal_encodeFields(thisAny, schema, stream);
318
- }
319
- function internal_decodeFields(thisAny, bitField, hasOptionalFields, schema, stream, factory) {
320
- // encodeFields base class first
321
- if (schema._baseSchema && schema._baseSchema.fields.length) {
322
- internal_decodeFields(thisAny, bitField, hasOptionalFields, schema._baseSchema, stream, factory);
323
- }
324
- for (const field of schema.fields) {
325
- // ignore fields that have a switch bit when bit is not set
326
- if (hasOptionalFields && field.switchBit !== undefined) {
327
- // tslint:disable-next-line:no-bitwise
328
- if ((bitField & (1 << field.switchBit)) === 0) {
329
- thisAny[field.name] = undefined;
330
- continue;
331
- }
332
- else {
333
- if (field.category === node_opcua_factory_1.FieldCategory.complex && thisAny[field.name] === undefined) {
334
- // need to create empty structure for deserialisation
335
- initializeField(field, thisAny, {}, schema, factory);
336
- }
337
- }
338
- }
339
- switch (field.category) {
340
- case node_opcua_factory_1.FieldCategory.complex:
341
- decodeArrayOrElement(factory, field, thisAny, stream);
342
- break;
343
- case node_opcua_factory_1.FieldCategory.enumeration:
344
- case node_opcua_factory_1.FieldCategory.basic:
345
- decodeArrayOrElement(factory, field, thisAny, stream, field.schema.decode);
346
- break;
347
- default:
348
- /* istanbul ignore next*/
349
- throw new Error("Invalid category " + field.category + " " + node_opcua_factory_1.FieldCategory[field.category]);
350
- }
351
- }
352
- }
353
- function decodeFields(thisAny, schema, stream, factory) {
354
- // ============ Deal with switchBits
355
- const hasOptionalFields = hasOptionalFieldsF(schema);
356
- let bitField = 0;
357
- if (hasOptionalFields && stream.buffer.length - stream.length > 0) {
358
- bitField = stream.readUInt32();
359
- }
360
- internal_decodeFields(thisAny, bitField, hasOptionalFields, schema, stream, factory);
361
- }
362
- function ___fieldToJson(field, value) {
363
- switch (field.category) {
364
- case node_opcua_factory_1.FieldCategory.complex:
365
- return value ? value === null || value === void 0 ? void 0 : value.toJSON() : null;
366
- case node_opcua_factory_1.FieldCategory.enumeration:
367
- case node_opcua_factory_1.FieldCategory.basic:
368
- return value instanceof Date ? new Date(value.getTime()) : (value === null || value === void 0 ? void 0 : value.toJSON) ? value === null || value === void 0 ? void 0 : value.toJSON() : value;
369
- default:
370
- /* istanbul ignore next*/
371
- throw new Error("Invalid category " + field.category + " " + node_opcua_factory_1.FieldCategory[field.category]);
372
- }
373
- }
374
- function fieldToJSON(field, value) {
375
- if (field.isArray) {
376
- if (value) {
377
- return value.map(___fieldToJson.bind(null, field));
378
- }
379
- }
380
- else {
381
- return ___fieldToJson(field, value);
382
- }
383
- }
384
- function encodeToJson(thisAny, schema, pojo) {
385
- if (schema._baseSchema && schema._baseSchema.fields.length) {
386
- encodeToJson(thisAny, schema._baseSchema, pojo);
387
- }
388
- for (const field of schema.fields) {
389
- const value = thisAny[field.name];
390
- if (value === undefined) {
391
- continue;
392
- }
393
- pojo[field.name] = fieldToJSON(field, value);
394
- }
395
- }
396
- const _private = new WeakMap();
397
- class DynamicExtensionObject extends node_opcua_extension_object_1.ExtensionObject {
398
- constructor(options, schema, factory) {
399
- (0, node_opcua_assert_1.assert)(schema, "expecting a schema here ");
400
- (0, node_opcua_assert_1.assert)(factory, "expecting a DataTypeFactory");
401
- super(options);
402
- options = options || {};
403
- _private.set(this, { schema, factory });
404
- (0, node_opcua_factory_1.check_options_correctness_against_schema)(this, this.schema, options);
405
- initializeFields(this, options, this.schema, factory, { caseInsensitive: true });
406
- }
407
- encode(stream) {
408
- super.encode(stream);
409
- encodeFields(this, this.schema, stream);
410
- }
411
- decode(stream) {
412
- super.decode(stream);
413
- decodeFields(this, this.schema, stream, _private.get(this).factory);
414
- }
415
- get schema() {
416
- const r = _private.get(this);
417
- return r.schema;
418
- }
419
- toJSON() {
420
- const pojo = {};
421
- encodeToJson(this, this.schema, pojo);
422
- return pojo;
423
- }
424
- }
425
- exports.DynamicExtensionObject = DynamicExtensionObject;
426
- DynamicExtensionObject.schema = node_opcua_extension_object_1.ExtensionObject.schema;
427
- DynamicExtensionObject.possibleFields = [];
428
- // tslint:disable-next-line:max-classes-per-file
429
- class UnionBaseClass extends node_opcua_factory_1.BaseUAObject {
430
- // eslint-disable-next-line max-statements
431
- constructor(options, schema, factory) {
432
- super();
433
- (0, node_opcua_assert_1.assert)(schema, "expecting a schema here ");
434
- (0, node_opcua_assert_1.assert)(factory, "expecting a typeDic");
435
- options = options || {};
436
- _private.set(this, { schema });
437
- (0, node_opcua_factory_1.check_options_correctness_against_schema)(this, this.schema, options);
438
- let uniqueFieldHasBeenFound = false;
439
- let switchFieldName = "";
440
- // finding fields that are in options but not in schema!
441
- for (const field of this.schema.fields) {
442
- const name = field.name;
443
- if (field.switchValue === undefined) {
444
- // this is the switch value field
445
- switchFieldName = field.name;
446
- continue;
447
- }
448
- (0, node_opcua_assert_1.assert)(switchFieldName.length > 0, "It seems that there is no switch field in union schema");
449
- (0, node_opcua_assert_1.assert)(field.switchValue !== undefined, "union schema must only have one switched value field");
450
- // dealing with optional fields
451
- const value = getFieldValue(field, options);
452
- /* istanbul ignore next */
453
- if (uniqueFieldHasBeenFound && value !== undefined) {
454
- // let try to be helpful for the developper by providing some hint
455
- debugLog(this.schema);
456
- throw new Error("union must have only one choice in " +
457
- JSON.stringify(options) +
458
- "\n found while investigating " +
459
- field.name +
460
- "\n switchFieldName = " +
461
- switchFieldName);
462
- }
463
- if (options[switchFieldName] !== undefined) {
464
- // then options[switchFieldName] must equal
465
- if (options[switchFieldName] !== field.switchValue) {
466
- continue;
467
- }
468
- }
469
- else {
470
- // the is no switchFieldName , in this case the i
471
- if (value === undefined) {
472
- continue;
473
- }
474
- }
475
- uniqueFieldHasBeenFound = true;
476
- this[switchFieldName] = field.switchValue;
477
- switch (field.category) {
478
- case node_opcua_factory_1.FieldCategory.complex: {
479
- const constuctor = factory.getStructureTypeConstructor(field.fieldType);
480
- // getOrCreateConstructor(field.fieldType, factory) || BaseUAObject;
481
- if (field.isArray) {
482
- this[name] = (value || []).map((x) => (constuctor ? new constuctor(x) : null));
483
- }
484
- else {
485
- this[name] = constuctor ? new constuctor(value) : null;
486
- }
487
- // xx processStructuredType(fieldSchema);
488
- break;
489
- }
490
- case node_opcua_factory_1.FieldCategory.enumeration:
491
- case node_opcua_factory_1.FieldCategory.basic:
492
- if (field.isArray) {
493
- this[name] = (0, node_opcua_factory_1.initialize_field_array)(field, value);
494
- }
495
- else {
496
- this[name] = (0, node_opcua_factory_1.initialize_field)(field, value);
497
- }
498
- break;
499
- }
500
- }
501
- if (!uniqueFieldHasBeenFound) {
502
- if (Object.keys(options).length === 0) {
503
- this[switchFieldName] = 0x00;
504
- return;
505
- }
506
- const r = schema.fields
507
- .filter((f) => f.switchValue !== undefined)
508
- .map((f) => f.name)
509
- .join(" , ");
510
- // it is possible also that the switchfield value do not correspond to a valid field
511
- const foundFieldForSwitchValue = schema.fields.findIndex((f) => f.switchValue !== undefined && f.switchValue === options[switchFieldName]);
512
- if (foundFieldForSwitchValue) {
513
- // throw new Error(this.schema.name + ": cannot find field with value "
514
- // + options[switchFieldName]);
515
- }
516
- else {
517
- console.log(this.schema);
518
- throw new Error(this.schema.name + ": At least one of [ " + r + " ] must be specified in " + JSON.stringify(options));
519
- }
520
- }
521
- }
522
- encode(stream) {
523
- const switchFieldName = this.schema.fields[0].name;
524
- const switchValue = this[switchFieldName];
525
- if (typeof switchValue !== "number") {
526
- throw new Error("Invalid switchValue " + switchFieldName + " value = " + switchValue);
527
- }
528
- stream.writeUInt32(switchValue);
529
- for (const field of this.schema.fields) {
530
- if (field.switchValue === undefined || field.switchValue !== switchValue) {
531
- continue;
532
- }
533
- switch (field.category) {
534
- case node_opcua_factory_1.FieldCategory.complex:
535
- encodeArrayOrElement(field, this, stream);
536
- break;
537
- case node_opcua_factory_1.FieldCategory.enumeration:
538
- case node_opcua_factory_1.FieldCategory.basic:
539
- encodeArrayOrElement(field, this, stream, field.schema.encode);
540
- break;
541
- default:
542
- /* istanbul ignore next*/
543
- throw new Error("Invalid category " + field.category + " " + node_opcua_factory_1.FieldCategory[field.category]);
544
- }
545
- break;
546
- }
547
- }
548
- decode(stream) {
549
- const factory = this.schema.$$factory;
550
- const switchValue = stream.readUInt32();
551
- const switchFieldName = this.schema.fields[0].name;
552
- this[switchFieldName] = switchValue;
553
- for (const field of this.schema.fields) {
554
- if (field.switchValue === undefined || field.switchValue !== switchValue) {
555
- continue;
556
- }
557
- switch (field.category) {
558
- case node_opcua_factory_1.FieldCategory.complex:
559
- decodeArrayOrElement(factory, field, this, stream);
560
- break;
561
- case node_opcua_factory_1.FieldCategory.enumeration:
562
- case node_opcua_factory_1.FieldCategory.basic:
563
- decodeArrayOrElement(factory, field, this, stream, field.schema.decode);
564
- break;
565
- default:
566
- /* istanbul ignore next*/
567
- throw new Error("Invalid category " + field.category + " " + node_opcua_factory_1.FieldCategory[field.category]);
568
- }
569
- break;
570
- }
571
- }
572
- get schema() {
573
- return _private.get(this).schema;
574
- }
575
- toString() {
576
- return super.toString();
577
- }
578
- toJSON() {
579
- const pojo = {};
580
- const switchFieldName = this.schema.fields[0].name;
581
- const switchValue = this[switchFieldName];
582
- if (typeof switchValue !== "number") {
583
- throw new Error("Invalid switchValue " + switchValue);
584
- }
585
- pojo[switchFieldName] = switchValue;
586
- for (const field of this.schema.fields) {
587
- if (field.switchValue === undefined || field.switchValue !== switchValue) {
588
- continue;
589
- }
590
- const value = this[field.name];
591
- if (value === undefined) {
592
- continue;
593
- }
594
- pojo[field.originalName] = fieldToJSON(field, value);
595
- break;
596
- }
597
- return pojo;
598
- }
599
- }
600
- function _createDynamicUnionConstructor(schema, factory) {
601
- const possibleFields = schema.fields.map((x) => x.name);
602
- // tslint:disable-next-line:max-classes-per-file
603
- class UNION extends UnionBaseClass {
604
- constructor(options) {
605
- super(options, schema, factory);
606
- (0, node_opcua_assert_1.assert)(this.schema === schema);
607
- }
608
- }
609
- UNION.possibleFields = possibleFields;
610
- UNION.schema = schema;
611
- // to do : may be remove DataType suffix here ?
612
- Object.defineProperty(UNION, "name", { value: schema.name });
613
- return UNION;
614
- }
615
- function createDynamicObjectConstructor(schema, dataTypeFactory) {
616
- var _a;
617
- const schemaPriv = schema;
618
- if (schemaPriv.$Constructor) {
619
- return schemaPriv.$Constructor;
620
- }
621
- const dataTypeNodeId = schemaPriv.id;
622
- if (schema.baseType === "Union") {
623
- const UNIONConstructor = _createDynamicUnionConstructor(schema, dataTypeFactory);
624
- schemaPriv.$Constructor = UNIONConstructor;
625
- dataTypeFactory.registerClassDefinition(dataTypeNodeId, schema.name, UNIONConstructor);
626
- return UNIONConstructor;
627
- }
628
- let possibleFields = schema.fields.map((x) => x.name);
629
- let BaseClass = DynamicExtensionObject;
630
- if (schema.baseType !== "ExtensionObject" &&
631
- schema.baseType !== "OptionSet" &&
632
- schema.baseType !== "DataTypeDescription" &&
633
- schema.baseType !== "DataTypeDefinition" &&
634
- schema.baseType !== "EnumValueType" &&
635
- schema.baseType !== "Structure") {
636
- try {
637
- const baseSchema = dataTypeFactory.getStructuredTypeSchema(schema.baseType);
638
- schema._baseSchema = baseSchema;
639
- if (((_a = baseSchema.encodingDefaultBinary) === null || _a === void 0 ? void 0 : _a.value) === 0) {
640
- // is abstract
641
- }
642
- else {
643
- BaseClass = getOrCreateConstructor(schema.baseType, dataTypeFactory);
644
- if (!BaseClass) {
645
- throw new Error("Cannot find base class : " + schema.baseType);
646
- }
647
- if (BaseClass.possibleFields) {
648
- possibleFields = BaseClass.possibleFields.concat(possibleFields);
649
- }
650
- schema._baseSchema = BaseClass.schema;
651
- }
652
- }
653
- catch (err) {
654
- // xx console.log("createDynamicObjectConstructor err= ", err.message);
655
- }
656
- }
657
- // tslint:disable-next-line:max-classes-per-file
658
- class EXTENSION extends BaseClass {
659
- constructor(options, schema2, factory2) {
660
- super(options, schema2 ? schema2 : EXTENSION.schema, factory2 ? factory2 : dataTypeFactory);
661
- }
662
- static get schema() {
663
- return schema;
664
- }
665
- toString() {
666
- return super.toString();
667
- }
668
- toJSON() {
669
- const pojo = {};
670
- encodeToJson(this, this.schema, pojo);
671
- return pojo;
672
- }
673
- encode(stream) {
674
- super.encode(stream);
675
- }
676
- decode(stream) {
677
- super.decode(stream);
678
- }
679
- }
680
- EXTENSION.encodingDefaultXml = new node_opcua_nodeid_1.ExpandedNodeId(node_opcua_nodeid_1.NodeIdType.NUMERIC, 0, 0);
681
- EXTENSION.encodingDefaultBinary = new node_opcua_nodeid_1.ExpandedNodeId(node_opcua_nodeid_1.NodeIdType.NUMERIC, 0, 0);
682
- EXTENSION.possibleFields = possibleFields;
683
- // to do : may be remove DataType suffix here ?
684
- Object.defineProperty(EXTENSION, "name", { value: schema.name });
685
- schemaPriv.$Constructor = EXTENSION;
686
- EXTENSION.encodingDefaultBinary = schema.encodingDefaultBinary;
687
- dataTypeFactory.registerClassDefinition(dataTypeNodeId, schema.name, EXTENSION);
688
- return EXTENSION;
689
- }
690
- exports.createDynamicObjectConstructor = createDynamicObjectConstructor;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDynamicObjectConstructor = exports.DynamicExtensionObject = exports.getOrCreateConstructor = void 0;
4
+ /**
5
+ * @module node-opcua-schemas
6
+ */
7
+ const node_opcua_assert_1 = require("node-opcua-assert");
8
+ const node_opcua_debug_1 = require("node-opcua-debug");
9
+ const node_opcua_extension_object_1 = require("node-opcua-extension-object");
10
+ const node_opcua_variant_1 = require("node-opcua-variant");
11
+ const node_opcua_factory_1 = require("node-opcua-factory");
12
+ const node_opcua_nodeid_1 = require("node-opcua-nodeid");
13
+ const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
14
+ const errorLog = (0, node_opcua_debug_1.make_errorLog)(__filename);
15
+ const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
16
+ function getOrCreateConstructor(dataTypeName, dataTypeFactory, encodingDefaultBinary, encodingDefaultXml) {
17
+ if (dataTypeFactory.hasStructuredType(dataTypeName)) {
18
+ return dataTypeFactory.getStructureTypeConstructor(dataTypeName);
19
+ }
20
+ const schema = dataTypeFactory.getStructuredTypeSchema(dataTypeName);
21
+ // istanbul ignore next
22
+ if (!schema) {
23
+ throw new Error("Unknown type in dictionary " + dataTypeName);
24
+ }
25
+ const constructor = createDynamicObjectConstructor(schema, dataTypeFactory);
26
+ if (!constructor) {
27
+ return constructor;
28
+ }
29
+ // istanbul ignore next
30
+ if (!dataTypeFactory.hasStructuredType(dataTypeName)) {
31
+ dataTypeFactory.registerClassDefinition(schema.id, dataTypeName, constructor);
32
+ return constructor;
33
+ // hrow new Error("constructor should now be registered - " + fieldType);
34
+ }
35
+ if (encodingDefaultBinary && encodingDefaultBinary.value !== 0) {
36
+ schema.encodingDefaultBinary = encodingDefaultBinary;
37
+ schema.encodingDefaultXml = encodingDefaultXml;
38
+ constructor.encodingDefaultBinary = encodingDefaultBinary;
39
+ constructor.encodingDefaultXml = encodingDefaultXml;
40
+ dataTypeFactory.associateWithBinaryEncoding(dataTypeName, encodingDefaultBinary);
41
+ }
42
+ return constructor;
43
+ }
44
+ exports.getOrCreateConstructor = getOrCreateConstructor;
45
+ function encodeElement(field, element, stream, encodeFunc) {
46
+ if (encodeFunc) {
47
+ encodeFunc(element, stream);
48
+ }
49
+ else {
50
+ // istanbul ignore next
51
+ if (!element.encode) {
52
+ throw new Error("encodeArrayOrElement: object field " + field.name + " has no encode method and encodeFunc is missing");
53
+ }
54
+ if (field.allowSubType) {
55
+ (0, node_opcua_extension_object_1.encodeExtensionObject)(element, stream);
56
+ // new Variant({ dataType: DataType.ExtensionObject, value: element }).encode(stream);
57
+ }
58
+ else {
59
+ element.encode(stream);
60
+ }
61
+ }
62
+ }
63
+ function encodeArrayOrElement(field, obj, stream, encodeFunc) {
64
+ if (field.isArray) {
65
+ const array = obj[field.name];
66
+ if (!array) {
67
+ stream.writeUInt32(0xffffffff);
68
+ }
69
+ else {
70
+ stream.writeUInt32(array.length);
71
+ for (const e of array) {
72
+ encodeElement(field, e, stream, encodeFunc);
73
+ }
74
+ }
75
+ }
76
+ else {
77
+ encodeElement(field, obj[field.name], stream, encodeFunc);
78
+ }
79
+ }
80
+ function decodeElement(factory, field, stream, decodeFunc) {
81
+ if (decodeFunc) {
82
+ return decodeFunc(stream);
83
+ }
84
+ else {
85
+ if (field.allowSubType) {
86
+ const element = (0, node_opcua_extension_object_1.decodeExtensionObject)(stream);
87
+ return element;
88
+ }
89
+ else {
90
+ // construct an instance
91
+ const constructor = factory.getStructureTypeConstructor(field.fieldType);
92
+ const element = new constructor({});
93
+ element.decode(stream);
94
+ return element;
95
+ }
96
+ }
97
+ }
98
+ function decodeArrayOrElement(factory, field, obj, stream, decodeFunc) {
99
+ if (field.isArray) {
100
+ const array = [];
101
+ const nbElements = stream.readUInt32();
102
+ if (nbElements === 0xffffffff) {
103
+ obj[field.name] = null;
104
+ }
105
+ else {
106
+ for (let i = 0; i < nbElements; i++) {
107
+ const element = decodeElement(factory, field, stream, decodeFunc);
108
+ array.push(element);
109
+ }
110
+ obj[field.name] = array;
111
+ }
112
+ }
113
+ else {
114
+ obj[field.name] = decodeElement(factory, field, stream, decodeFunc);
115
+ }
116
+ }
117
+ function isSubtype(factory, dataTypeNodeId, schema) {
118
+ var _a;
119
+ if (dataTypeNodeId.toString() === schema.dataTypeNodeId.toString()) {
120
+ return true;
121
+ }
122
+ if (!schema._baseSchema || !((_a = schema._baseSchema) === null || _a === void 0 ? void 0 : _a.dataTypeNodeId))
123
+ return false;
124
+ const c = factory.getConstructorForDataType(schema._baseSchema.dataTypeNodeId);
125
+ if (!c) {
126
+ return false;
127
+ }
128
+ return isSubtype(factory, dataTypeNodeId, c.schema);
129
+ }
130
+ function _validateSubType(factory, field, value) {
131
+ (0, node_opcua_assert_1.assert)(field.allowSubType);
132
+ if (!value) {
133
+ value = { dataType: node_opcua_variant_1.DataType.Null, value: null };
134
+ // const msg = "initializeField: field { dataType,value} is required here";
135
+ // errorLog(msg);
136
+ // throw new Error(msg);
137
+ return;
138
+ }
139
+ if (field.category === "basic") {
140
+ if (!Object.prototype.hasOwnProperty.call(value, "dataType")) {
141
+ const msg = "initializeField: field that allow subtype must be a Variant like and have a dataType property";
142
+ errorLog(msg);
143
+ throw new Error(msg);
144
+ }
145
+ const c = factory.getBuiltInTypeByDataType((0, node_opcua_nodeid_1.coerceNodeId)(`i=${value.dataType}`, 0));
146
+ const d = factory.getBuiltInType(field.fieldType);
147
+ if (c && c.isSubTypeOf(d)) {
148
+ return;
149
+ }
150
+ const msg = "initializeField: invalid subtype for field " +
151
+ field.name +
152
+ " expecting " +
153
+ field.fieldType +
154
+ " but got " +
155
+ node_opcua_variant_1.DataType[value.dataType];
156
+ errorLog(msg);
157
+ throw new Error(msg);
158
+ }
159
+ else {
160
+ if (value !== null && !(value instanceof node_opcua_extension_object_1.ExtensionObject)) {
161
+ errorLog("initializeField: array element is not an ExtensionObject");
162
+ throw new Error(`${field.name}: array element must be an ExtensionObject`);
163
+ }
164
+ const e = value;
165
+ if (!isSubtype(factory, field.dataType, e.schema)) {
166
+ const msg = "initializeField: invalid subtype for field " +
167
+ field.name +
168
+ " expecting " +
169
+ field.fieldType +
170
+ " but got " +
171
+ e.schema.id.toString() +
172
+ " " +
173
+ e.schema.name;
174
+ errorLog(msg);
175
+ throw new Error(msg);
176
+ }
177
+ }
178
+ }
179
+ function validateSubTypeA(factory, field, value) {
180
+ if (field.isArray) {
181
+ const arr = value || [];
182
+ for (const e of arr) {
183
+ // now check that element is of the correct type
184
+ _validateSubType(factory, field, e);
185
+ }
186
+ }
187
+ else {
188
+ _validateSubType(factory, field, value);
189
+ }
190
+ }
191
+ function initializeField(field, thisAny, options, schema, factory) {
192
+ const name = field.name;
193
+ const value = getFieldValue(field, options);
194
+ switch (field.category) {
195
+ case node_opcua_factory_1.FieldCategory.complex: {
196
+ if (field.allowSubType) {
197
+ validateSubTypeA(factory, field, value);
198
+ if (field.isArray) {
199
+ const arr = value || [];
200
+ thisAny[name] = arr.map((x) => x.clone());
201
+ }
202
+ else {
203
+ const e = value;
204
+ if (e !== null && !(e instanceof node_opcua_extension_object_1.ExtensionObject)) {
205
+ errorLog("initializeField: array element is not an ExtensionObject");
206
+ }
207
+ // now check that element is of the correct type
208
+ thisAny[name] = e.clone();
209
+ }
210
+ }
211
+ else {
212
+ const constructor = factory.getStructureTypeConstructor(field.fieldType);
213
+ if (field.isArray) {
214
+ const arr = value || [];
215
+ thisAny[name] = arr.map((x) => (constructor ? new constructor(x) : null));
216
+ }
217
+ else {
218
+ thisAny[name] = constructor ? new constructor(value) : null;
219
+ }
220
+ }
221
+ // getOrCreateConstructor(field.fieldType, factory) || BaseUAObject;
222
+ // xx processStructuredType(fieldSchema);
223
+ break;
224
+ }
225
+ case node_opcua_factory_1.FieldCategory.enumeration:
226
+ case node_opcua_factory_1.FieldCategory.basic:
227
+ if (field.allowSubType) {
228
+ validateSubTypeA(factory, field, value);
229
+ }
230
+ if (field.isArray) {
231
+ thisAny[name] = (0, node_opcua_factory_1.initialize_field_array)(field, value, factory);
232
+ }
233
+ else {
234
+ thisAny[name] = (0, node_opcua_factory_1.initialize_field)(field, value, factory);
235
+ }
236
+ break;
237
+ }
238
+ }
239
+ function getFieldValue(field, options) {
240
+ return options[field.name] !== undefined ? options[field.name] : options[field.originalName];
241
+ }
242
+ function initializeFields(thisAny, options, schema, factory, params) {
243
+ // initialize base class first
244
+ if (schema._baseSchema && schema._baseSchema.fields.length) {
245
+ initializeFields(thisAny, options, schema._baseSchema, factory, params);
246
+ }
247
+ // finding fields that are in options but not in schema!
248
+ for (const field of schema.fields) {
249
+ const name = field.name;
250
+ const value = getFieldValue(field, options);
251
+ // dealing with optional fields
252
+ if (field.switchBit !== undefined && value === undefined) {
253
+ thisAny[name] = undefined;
254
+ continue;
255
+ }
256
+ initializeField(field, thisAny, options, schema, factory);
257
+ }
258
+ }
259
+ function hasOptionalFieldsF(schema) {
260
+ if (schema.bitFields && schema.bitFields.length > 0) {
261
+ return true;
262
+ }
263
+ return schema._baseSchema ? hasOptionalFieldsF(schema._baseSchema) : false;
264
+ }
265
+ function _internal_encodeFields(thisAny, schema, stream) {
266
+ // encodeFields base class first
267
+ if (schema._baseSchema && schema._baseSchema.fields.length) {
268
+ _internal_encodeFields(thisAny, schema._baseSchema, stream);
269
+ }
270
+ for (const field of schema.fields) {
271
+ // ignore
272
+ if (field.switchBit !== undefined && thisAny[field.name] === undefined) {
273
+ continue;
274
+ }
275
+ switch (field.category) {
276
+ case node_opcua_factory_1.FieldCategory.complex:
277
+ encodeArrayOrElement(field, thisAny, stream);
278
+ break;
279
+ case node_opcua_factory_1.FieldCategory.enumeration:
280
+ case node_opcua_factory_1.FieldCategory.basic:
281
+ encodeArrayOrElement(field, thisAny, stream, field.schema.encode);
282
+ break;
283
+ default:
284
+ /* istanbul ignore next*/
285
+ throw new Error("Invalid category " + field.category + " " + node_opcua_factory_1.FieldCategory[field.category]);
286
+ }
287
+ }
288
+ }
289
+ function makeBitField(thisAny, schema, bo) {
290
+ const data = schema._baseSchema ? makeBitField(thisAny, schema._baseSchema, bo) : bo;
291
+ let { bitField, allOptional } = data;
292
+ const { offset } = data;
293
+ let nbOptionalFields = 0;
294
+ for (const field of schema.fields) {
295
+ if (field.switchBit === undefined) {
296
+ allOptional = false;
297
+ continue;
298
+ }
299
+ nbOptionalFields += 1;
300
+ if (thisAny[field.name] === undefined) {
301
+ continue;
302
+ }
303
+ // tslint:disable-next-line:no-bitwise
304
+ bitField |= 1 << (field.switchBit + offset);
305
+ }
306
+ return { bitField, offset: nbOptionalFields + offset, allOptional };
307
+ }
308
+ function encodeFields(thisAny, schema, stream) {
309
+ const hasOptionalFields = hasOptionalFieldsF(schema);
310
+ // ============ Deal with switchBits
311
+ if (hasOptionalFields) {
312
+ const { bitField, allOptional } = makeBitField(thisAny, schema, { bitField: 0, offset: 0, allOptional: true });
313
+ if (!(bitField === 0 && allOptional)) {
314
+ stream.writeUInt32(bitField);
315
+ }
316
+ }
317
+ _internal_encodeFields(thisAny, schema, stream);
318
+ }
319
+ function internal_decodeFields(thisAny, bitField, hasOptionalFields, schema, stream, factory) {
320
+ // encodeFields base class first
321
+ if (schema._baseSchema && schema._baseSchema.fields.length) {
322
+ internal_decodeFields(thisAny, bitField, hasOptionalFields, schema._baseSchema, stream, factory);
323
+ }
324
+ for (const field of schema.fields) {
325
+ // ignore fields that have a switch bit when bit is not set
326
+ if (hasOptionalFields && field.switchBit !== undefined) {
327
+ // tslint:disable-next-line:no-bitwise
328
+ if ((bitField & (1 << field.switchBit)) === 0) {
329
+ thisAny[field.name] = undefined;
330
+ continue;
331
+ }
332
+ else {
333
+ if (field.category === node_opcua_factory_1.FieldCategory.complex && thisAny[field.name] === undefined) {
334
+ // need to create empty structure for deserialisation
335
+ initializeField(field, thisAny, {}, schema, factory);
336
+ }
337
+ }
338
+ }
339
+ switch (field.category) {
340
+ case node_opcua_factory_1.FieldCategory.complex:
341
+ decodeArrayOrElement(factory, field, thisAny, stream);
342
+ break;
343
+ case node_opcua_factory_1.FieldCategory.enumeration:
344
+ case node_opcua_factory_1.FieldCategory.basic:
345
+ decodeArrayOrElement(factory, field, thisAny, stream, field.schema.decode);
346
+ break;
347
+ default:
348
+ /* istanbul ignore next*/
349
+ throw new Error("Invalid category " + field.category + " " + node_opcua_factory_1.FieldCategory[field.category]);
350
+ }
351
+ }
352
+ }
353
+ function decodeFields(thisAny, schema, stream, factory) {
354
+ // ============ Deal with switchBits
355
+ const hasOptionalFields = hasOptionalFieldsF(schema);
356
+ let bitField = 0;
357
+ if (hasOptionalFields && stream.buffer.length - stream.length > 0) {
358
+ bitField = stream.readUInt32();
359
+ }
360
+ internal_decodeFields(thisAny, bitField, hasOptionalFields, schema, stream, factory);
361
+ }
362
+ function ___fieldToJson(field, value) {
363
+ switch (field.category) {
364
+ case node_opcua_factory_1.FieldCategory.complex:
365
+ return value ? value === null || value === void 0 ? void 0 : value.toJSON() : null;
366
+ case node_opcua_factory_1.FieldCategory.enumeration:
367
+ case node_opcua_factory_1.FieldCategory.basic:
368
+ return value instanceof Date ? new Date(value.getTime()) : (value === null || value === void 0 ? void 0 : value.toJSON) ? value === null || value === void 0 ? void 0 : value.toJSON() : value;
369
+ default:
370
+ /* istanbul ignore next*/
371
+ throw new Error("Invalid category " + field.category + " " + node_opcua_factory_1.FieldCategory[field.category]);
372
+ }
373
+ }
374
+ function fieldToJSON(field, value) {
375
+ if (field.isArray) {
376
+ if (value) {
377
+ return value.map(___fieldToJson.bind(null, field));
378
+ }
379
+ }
380
+ else {
381
+ return ___fieldToJson(field, value);
382
+ }
383
+ }
384
+ function encodeToJson(thisAny, schema, pojo) {
385
+ if (schema._baseSchema && schema._baseSchema.fields.length) {
386
+ encodeToJson(thisAny, schema._baseSchema, pojo);
387
+ }
388
+ for (const field of schema.fields) {
389
+ const value = thisAny[field.name];
390
+ if (value === undefined) {
391
+ continue;
392
+ }
393
+ pojo[field.name] = fieldToJSON(field, value);
394
+ }
395
+ }
396
+ const _private = new WeakMap();
397
+ class DynamicExtensionObject extends node_opcua_extension_object_1.ExtensionObject {
398
+ constructor(options, schema, factory) {
399
+ (0, node_opcua_assert_1.assert)(schema, "expecting a schema here ");
400
+ (0, node_opcua_assert_1.assert)(factory, "expecting a DataTypeFactory");
401
+ super(options);
402
+ options = options || {};
403
+ _private.set(this, { schema, factory });
404
+ (0, node_opcua_factory_1.check_options_correctness_against_schema)(this, this.schema, options);
405
+ initializeFields(this, options, this.schema, factory, { caseInsensitive: true });
406
+ }
407
+ encode(stream) {
408
+ super.encode(stream);
409
+ encodeFields(this, this.schema, stream);
410
+ }
411
+ decode(stream) {
412
+ super.decode(stream);
413
+ decodeFields(this, this.schema, stream, _private.get(this).factory);
414
+ }
415
+ get schema() {
416
+ const r = _private.get(this);
417
+ return r.schema;
418
+ }
419
+ toJSON() {
420
+ const pojo = {};
421
+ encodeToJson(this, this.schema, pojo);
422
+ return pojo;
423
+ }
424
+ }
425
+ exports.DynamicExtensionObject = DynamicExtensionObject;
426
+ DynamicExtensionObject.schema = node_opcua_extension_object_1.ExtensionObject.schema;
427
+ DynamicExtensionObject.possibleFields = [];
428
+ // tslint:disable-next-line:max-classes-per-file
429
+ class UnionBaseClass extends node_opcua_factory_1.BaseUAObject {
430
+ // eslint-disable-next-line max-statements
431
+ constructor(options, schema, factory) {
432
+ super();
433
+ (0, node_opcua_assert_1.assert)(schema, "expecting a schema here ");
434
+ (0, node_opcua_assert_1.assert)(factory, "expecting a typeDic");
435
+ options = options || {};
436
+ _private.set(this, { schema });
437
+ (0, node_opcua_factory_1.check_options_correctness_against_schema)(this, this.schema, options);
438
+ let uniqueFieldHasBeenFound = false;
439
+ let switchFieldName = "";
440
+ // finding fields that are in options but not in schema!
441
+ for (const field of this.schema.fields) {
442
+ const name = field.name;
443
+ if (field.switchValue === undefined) {
444
+ // this is the switch value field
445
+ switchFieldName = field.name;
446
+ continue;
447
+ }
448
+ (0, node_opcua_assert_1.assert)(switchFieldName.length > 0, "It seems that there is no switch field in union schema");
449
+ (0, node_opcua_assert_1.assert)(field.switchValue !== undefined, "union schema must only have one switched value field");
450
+ // dealing with optional fields
451
+ const value = getFieldValue(field, options);
452
+ /* istanbul ignore next */
453
+ if (uniqueFieldHasBeenFound && value !== undefined) {
454
+ // let try to be helpful for the developper by providing some hint
455
+ debugLog(this.schema);
456
+ throw new Error("union must have only one choice in " +
457
+ JSON.stringify(options) +
458
+ "\n found while investigating " +
459
+ field.name +
460
+ "\n switchFieldName = " +
461
+ switchFieldName);
462
+ }
463
+ if (options[switchFieldName] !== undefined) {
464
+ // then options[switchFieldName] must equal
465
+ if (options[switchFieldName] !== field.switchValue) {
466
+ continue;
467
+ }
468
+ }
469
+ else {
470
+ // the is no switchFieldName , in this case the i
471
+ if (value === undefined) {
472
+ continue;
473
+ }
474
+ }
475
+ uniqueFieldHasBeenFound = true;
476
+ this[switchFieldName] = field.switchValue;
477
+ switch (field.category) {
478
+ case node_opcua_factory_1.FieldCategory.complex: {
479
+ const constuctor = factory.getStructureTypeConstructor(field.fieldType);
480
+ // getOrCreateConstructor(field.fieldType, factory) || BaseUAObject;
481
+ if (field.isArray) {
482
+ this[name] = (value || []).map((x) => (constuctor ? new constuctor(x) : null));
483
+ }
484
+ else {
485
+ this[name] = constuctor ? new constuctor(value) : null;
486
+ }
487
+ // xx processStructuredType(fieldSchema);
488
+ break;
489
+ }
490
+ case node_opcua_factory_1.FieldCategory.enumeration:
491
+ case node_opcua_factory_1.FieldCategory.basic:
492
+ if (field.isArray) {
493
+ this[name] = (0, node_opcua_factory_1.initialize_field_array)(field, value);
494
+ }
495
+ else {
496
+ this[name] = (0, node_opcua_factory_1.initialize_field)(field, value);
497
+ }
498
+ break;
499
+ }
500
+ }
501
+ if (!uniqueFieldHasBeenFound) {
502
+ if (Object.keys(options).length === 0) {
503
+ this[switchFieldName] = 0x00;
504
+ return;
505
+ }
506
+ const r = schema.fields
507
+ .filter((f) => f.switchValue !== undefined)
508
+ .map((f) => f.name)
509
+ .join(" , ");
510
+ // it is possible also that the switchfield value do not correspond to a valid field
511
+ const foundFieldForSwitchValue = schema.fields.findIndex((f) => f.switchValue !== undefined && f.switchValue === options[switchFieldName]);
512
+ if (foundFieldForSwitchValue) {
513
+ // throw new Error(this.schema.name + ": cannot find field with value "
514
+ // + options[switchFieldName]);
515
+ }
516
+ else {
517
+ console.log(this.schema);
518
+ throw new Error(this.schema.name + ": At least one of [ " + r + " ] must be specified in " + JSON.stringify(options));
519
+ }
520
+ }
521
+ }
522
+ encode(stream) {
523
+ const switchFieldName = this.schema.fields[0].name;
524
+ const switchValue = this[switchFieldName];
525
+ if (typeof switchValue !== "number") {
526
+ throw new Error("Invalid switchValue " + switchFieldName + " value = " + switchValue);
527
+ }
528
+ stream.writeUInt32(switchValue);
529
+ for (const field of this.schema.fields) {
530
+ if (field.switchValue === undefined || field.switchValue !== switchValue) {
531
+ continue;
532
+ }
533
+ switch (field.category) {
534
+ case node_opcua_factory_1.FieldCategory.complex:
535
+ encodeArrayOrElement(field, this, stream);
536
+ break;
537
+ case node_opcua_factory_1.FieldCategory.enumeration:
538
+ case node_opcua_factory_1.FieldCategory.basic:
539
+ encodeArrayOrElement(field, this, stream, field.schema.encode);
540
+ break;
541
+ default:
542
+ /* istanbul ignore next*/
543
+ throw new Error("Invalid category " + field.category + " " + node_opcua_factory_1.FieldCategory[field.category]);
544
+ }
545
+ break;
546
+ }
547
+ }
548
+ decode(stream) {
549
+ const factory = this.schema.$$factory;
550
+ const switchValue = stream.readUInt32();
551
+ const switchFieldName = this.schema.fields[0].name;
552
+ this[switchFieldName] = switchValue;
553
+ for (const field of this.schema.fields) {
554
+ if (field.switchValue === undefined || field.switchValue !== switchValue) {
555
+ continue;
556
+ }
557
+ switch (field.category) {
558
+ case node_opcua_factory_1.FieldCategory.complex:
559
+ decodeArrayOrElement(factory, field, this, stream);
560
+ break;
561
+ case node_opcua_factory_1.FieldCategory.enumeration:
562
+ case node_opcua_factory_1.FieldCategory.basic:
563
+ decodeArrayOrElement(factory, field, this, stream, field.schema.decode);
564
+ break;
565
+ default:
566
+ /* istanbul ignore next*/
567
+ throw new Error("Invalid category " + field.category + " " + node_opcua_factory_1.FieldCategory[field.category]);
568
+ }
569
+ break;
570
+ }
571
+ }
572
+ get schema() {
573
+ return _private.get(this).schema;
574
+ }
575
+ toString() {
576
+ return super.toString();
577
+ }
578
+ toJSON() {
579
+ const pojo = {};
580
+ const switchFieldName = this.schema.fields[0].name;
581
+ const switchValue = this[switchFieldName];
582
+ if (typeof switchValue !== "number") {
583
+ throw new Error("Invalid switchValue " + switchValue);
584
+ }
585
+ pojo[switchFieldName] = switchValue;
586
+ for (const field of this.schema.fields) {
587
+ if (field.switchValue === undefined || field.switchValue !== switchValue) {
588
+ continue;
589
+ }
590
+ const value = this[field.name];
591
+ if (value === undefined) {
592
+ continue;
593
+ }
594
+ pojo[field.originalName] = fieldToJSON(field, value);
595
+ break;
596
+ }
597
+ return pojo;
598
+ }
599
+ }
600
+ function _createDynamicUnionConstructor(schema, factory) {
601
+ const possibleFields = schema.fields.map((x) => x.name);
602
+ // tslint:disable-next-line:max-classes-per-file
603
+ class UNION extends UnionBaseClass {
604
+ constructor(options) {
605
+ super(options, schema, factory);
606
+ (0, node_opcua_assert_1.assert)(this.schema === schema);
607
+ }
608
+ }
609
+ UNION.possibleFields = possibleFields;
610
+ UNION.schema = schema;
611
+ // to do : may be remove DataType suffix here ?
612
+ Object.defineProperty(UNION, "name", { value: schema.name });
613
+ return UNION;
614
+ }
615
+ function createDynamicObjectConstructor(schema, dataTypeFactory) {
616
+ var _a;
617
+ const schemaPriv = schema;
618
+ if (schemaPriv.$Constructor) {
619
+ return schemaPriv.$Constructor;
620
+ }
621
+ const dataTypeNodeId = schemaPriv.id;
622
+ if (schema.baseType === "Union") {
623
+ const UNIONConstructor = _createDynamicUnionConstructor(schema, dataTypeFactory);
624
+ schemaPriv.$Constructor = UNIONConstructor;
625
+ dataTypeFactory.registerClassDefinition(dataTypeNodeId, schema.name, UNIONConstructor);
626
+ return UNIONConstructor;
627
+ }
628
+ let possibleFields = schema.fields.map((x) => x.name);
629
+ let BaseClass = DynamicExtensionObject;
630
+ if (schema.baseType !== "ExtensionObject" &&
631
+ schema.baseType !== "OptionSet" &&
632
+ schema.baseType !== "DataTypeDescription" &&
633
+ schema.baseType !== "DataTypeDefinition" &&
634
+ schema.baseType !== "EnumValueType" &&
635
+ schema.baseType !== "Structure") {
636
+ try {
637
+ const baseSchema = dataTypeFactory.getStructuredTypeSchema(schema.baseType);
638
+ schema._baseSchema = baseSchema;
639
+ if (((_a = baseSchema.encodingDefaultBinary) === null || _a === void 0 ? void 0 : _a.value) === 0) {
640
+ // is abstract
641
+ }
642
+ else {
643
+ BaseClass = getOrCreateConstructor(schema.baseType, dataTypeFactory);
644
+ if (!BaseClass) {
645
+ throw new Error("Cannot find base class : " + schema.baseType);
646
+ }
647
+ if (BaseClass.possibleFields) {
648
+ possibleFields = BaseClass.possibleFields.concat(possibleFields);
649
+ }
650
+ schema._baseSchema = BaseClass.schema;
651
+ }
652
+ }
653
+ catch (err) {
654
+ // xx console.log("createDynamicObjectConstructor err= ", err.message);
655
+ }
656
+ }
657
+ // tslint:disable-next-line:max-classes-per-file
658
+ class EXTENSION extends BaseClass {
659
+ constructor(options, schema2, factory2) {
660
+ super(options, schema2 ? schema2 : EXTENSION.schema, factory2 ? factory2 : dataTypeFactory);
661
+ }
662
+ static get schema() {
663
+ return schema;
664
+ }
665
+ toString() {
666
+ return super.toString();
667
+ }
668
+ toJSON() {
669
+ const pojo = {};
670
+ encodeToJson(this, this.schema, pojo);
671
+ return pojo;
672
+ }
673
+ encode(stream) {
674
+ super.encode(stream);
675
+ }
676
+ decode(stream) {
677
+ super.decode(stream);
678
+ }
679
+ }
680
+ EXTENSION.encodingDefaultXml = new node_opcua_nodeid_1.ExpandedNodeId(node_opcua_nodeid_1.NodeIdType.NUMERIC, 0, 0);
681
+ EXTENSION.encodingDefaultBinary = new node_opcua_nodeid_1.ExpandedNodeId(node_opcua_nodeid_1.NodeIdType.NUMERIC, 0, 0);
682
+ EXTENSION.possibleFields = possibleFields;
683
+ // to do : may be remove DataType suffix here ?
684
+ Object.defineProperty(EXTENSION, "name", { value: schema.name });
685
+ schemaPriv.$Constructor = EXTENSION;
686
+ EXTENSION.encodingDefaultBinary = schema.encodingDefaultBinary;
687
+ dataTypeFactory.registerClassDefinition(dataTypeNodeId, schema.name, EXTENSION);
688
+ return EXTENSION;
689
+ }
690
+ exports.createDynamicObjectConstructor = createDynamicObjectConstructor;
691
691
  //# sourceMappingURL=dynamic_extension_object.js.map