node-opcua-factory 2.71.0 → 2.73.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.
Files changed (94) hide show
  1. package/dist/base_ua_object.d.ts +53 -0
  2. package/dist/base_ua_object.js +536 -0
  3. package/dist/base_ua_object.js.map +1 -0
  4. package/dist/basic_type.d.ts +40 -0
  5. package/dist/basic_type.js +119 -0
  6. package/dist/basic_type.js.map +1 -0
  7. package/dist/builtin_types.d.ts +46 -0
  8. package/dist/builtin_types.js +284 -0
  9. package/dist/builtin_types.js.map +1 -0
  10. package/dist/builtin_types_special.d.ts +5 -0
  11. package/dist/builtin_types_special.js +46 -0
  12. package/dist/builtin_types_special.js.map +1 -0
  13. package/dist/constructor_type.d.ts +15 -15
  14. package/dist/constructor_type.js +2 -2
  15. package/dist/datatype_factory.d.ts +36 -39
  16. package/dist/datatype_factory.js +305 -322
  17. package/dist/datatype_factory.js.map +1 -1
  18. package/dist/encode_decode.d.ts +9 -0
  19. package/dist/encode_decode.js +40 -0
  20. package/dist/encode_decode.js.map +1 -0
  21. package/dist/enumerations.d.ts +32 -0
  22. package/dist/enumerations.js +78 -0
  23. package/dist/enumerations.js.map +1 -0
  24. package/dist/factories_baseobject.d.ts +56 -56
  25. package/dist/factories_baseobject.js +534 -534
  26. package/dist/factories_basic_type.d.ts +40 -40
  27. package/dist/factories_basic_type.js +135 -135
  28. package/dist/factories_builtin_types.d.ts +32 -32
  29. package/dist/factories_builtin_types.js +261 -261
  30. package/dist/factories_builtin_types_special.d.ts +5 -5
  31. package/dist/factories_builtin_types_special.js +45 -45
  32. package/dist/factories_enumerations.d.ts +31 -31
  33. package/dist/factories_enumerations.js +77 -77
  34. package/dist/factories_factories.d.ts +17 -17
  35. package/dist/factories_factories.js +53 -53
  36. package/dist/factories_id_generator.d.ts +3 -3
  37. package/dist/factories_id_generator.js +21 -21
  38. package/dist/factories_schema_helpers.d.ts +27 -27
  39. package/dist/factories_schema_helpers.js +121 -121
  40. package/dist/factories_structuredTypeSchema.d.ts +45 -45
  41. package/dist/factories_structuredTypeSchema.js +276 -276
  42. package/dist/get_built_in_type.d.ts +0 -0
  43. package/dist/get_built_in_type.js +2 -0
  44. package/dist/get_built_in_type.js.map +1 -0
  45. package/dist/get_standard_data_type_factory.d.ts +12 -0
  46. package/dist/get_standard_data_type_factory.js +35 -0
  47. package/dist/get_standard_data_type_factory.js.map +1 -0
  48. package/dist/get_structured_type_schema.d.ts +4 -0
  49. package/dist/get_structured_type_schema.js +13 -0
  50. package/dist/get_structured_type_schema.js.map +1 -0
  51. package/dist/id_generator.d.ts +3 -0
  52. package/dist/id_generator.js +22 -0
  53. package/dist/id_generator.js.map +1 -0
  54. package/dist/index.d.ts +18 -15
  55. package/dist/index.js +34 -31
  56. package/dist/index.js.map +1 -1
  57. package/dist/nodeid_type.d.ts +13 -0
  58. package/dist/nodeid_type.js +19 -0
  59. package/dist/nodeid_type.js.map +1 -0
  60. package/dist/parameters.d.ts +3 -0
  61. package/dist/parameters.js +7 -0
  62. package/dist/parameters.js.map +1 -0
  63. package/dist/register_class_definition.d.ts +3 -0
  64. package/dist/register_class_definition.js +9 -0
  65. package/dist/register_class_definition.js.map +1 -0
  66. package/dist/schema_helpers.d.ts +24 -0
  67. package/dist/schema_helpers.js +100 -0
  68. package/dist/schema_helpers.js.map +1 -0
  69. package/dist/structured_type_schema.d.ts +44 -0
  70. package/dist/structured_type_schema.js +279 -0
  71. package/dist/structured_type_schema.js.map +1 -0
  72. package/dist/types.d.ts +151 -110
  73. package/dist/types.js +9 -51
  74. package/dist/types.js.map +1 -1
  75. package/package.json +7 -6
  76. package/source/{factories_baseobject.ts → base_ua_object.ts} +48 -44
  77. package/source/{factories_basic_type.ts → basic_type.ts} +7 -28
  78. package/source/{factories_builtin_types.ts → builtin_types.ts} +111 -89
  79. package/source/{factories_builtin_types_special.ts → builtin_types_special.ts} +2 -2
  80. package/source/datatype_factory.ts +44 -47
  81. package/source/encode_decode.ts +37 -0
  82. package/source/{factories_enumerations.ts → enumerations.ts} +6 -4
  83. package/source/get_built_in_type.ts +0 -0
  84. package/source/{factories_factories.ts → get_standard_data_type_factory.ts} +7 -25
  85. package/source/get_structured_type_schema.ts +10 -0
  86. package/source/{factories_id_generator.ts → id_generator.ts} +0 -0
  87. package/source/index.ts +14 -11
  88. package/source/nodeid_type.ts +17 -0
  89. package/source/parameters.ts +3 -0
  90. package/source/register_class_definition.ts +11 -0
  91. package/source/{factories_schema_helpers.ts → schema_helpers.ts} +15 -37
  92. package/source/{factories_structuredTypeSchema.ts → structured_type_schema.ts} +37 -36
  93. package/source/types.ts +104 -79
  94. package/source/constructor_type.ts +0 -18
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-opcua-factory",
3
- "version": "2.71.0",
3
+ "version": "2.73.1",
4
4
  "description": "pure nodejs OPCUA SDK - module -factory",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -9,18 +9,19 @@
9
9
  "lint": "eslint source",
10
10
  "format": "prettier --write source",
11
11
  "clean": "npx rimraf dist *.tsbuildinfo",
12
- "test": "echo no test"
12
+ "test": "mocha"
13
13
  },
14
14
  "dependencies": {
15
15
  "chalk": "4.1.2",
16
16
  "node-opcua-assert": "2.66.0",
17
- "node-opcua-basic-types": "2.71.0",
18
- "node-opcua-binary-stream": "2.71.0",
17
+ "node-opcua-basic-types": "2.73.0",
18
+ "node-opcua-binary-stream": "2.73.0",
19
+ "node-opcua-constants": "2.70.0",
19
20
  "node-opcua-debug": "2.71.0",
20
21
  "node-opcua-enum": "2.71.0",
21
22
  "node-opcua-guid": "2.66.0",
22
23
  "node-opcua-nodeid": "2.71.0",
23
- "node-opcua-status-code": "2.71.0",
24
+ "node-opcua-status-code": "2.73.0",
24
25
  "node-opcua-utils": "2.71.0"
25
26
  },
26
27
  "author": "Etienne Rossignon",
@@ -38,5 +39,5 @@
38
39
  "internet of things"
39
40
  ],
40
41
  "homepage": "http://node-opcua.github.io/",
41
- "gitHead": "10f7cc1e1cd30dfef75adad9cb709a78401fabf3"
42
+ "gitHead": "684a796e88e1732f418f2ada6aca2808e0115de8"
42
43
  }
@@ -8,16 +8,28 @@ import * as chalk from "chalk";
8
8
  import { assert } from "node-opcua-assert";
9
9
  import { AttributeIds } from "node-opcua-basic-types";
10
10
  import { BinaryStream, BinaryStreamSizeCalculator, OutputBinaryStream } from "node-opcua-binary-stream";
11
- import { hexDump } from "node-opcua-debug";
11
+ import { hexDump, make_errorLog } from "node-opcua-debug";
12
12
  import { NodeId } from "node-opcua-nodeid";
13
13
  import * as utils from "node-opcua-utils";
14
14
 
15
- import { getBuildInType } from "./factories_builtin_types";
16
- import { getEnumeration, hasEnumeration } from "./factories_enumerations";
17
- import { DataTypeFactory } from "./datatype_factory";
18
- import { getStructureTypeConstructor } from "./factories_factories";
19
- import { get_base_schema, StructuredTypeSchema } from "./factories_structuredTypeSchema";
20
- import { EnumerationDefinition, FieldCategory, StructuredTypeField, BuiltInTypeDefinition, FieldType } from "./types";
15
+ import { getBuiltInEnumeration, hasBuiltInEnumeration } from "./enumerations";
16
+ import { DataTypeFactory, _findFieldSchema } from "./datatype_factory";
17
+ import { getStructureTypeConstructor } from "./get_standard_data_type_factory";
18
+ import { get_base_schema } from "./structured_type_schema";
19
+ import {
20
+ EnumerationDefinition,
21
+ FieldCategory,
22
+ StructuredTypeField,
23
+ BuiltInTypeDefinition,
24
+ FieldType,
25
+ CommonInterface,
26
+ Func1,
27
+ IStructuredTypeSchema,
28
+ IBaseUAObject,
29
+ DecodeDebugOptions
30
+ } from "./types";
31
+
32
+ const errorLog = make_errorLog(__filename);
21
33
 
22
34
  function r(str: string, length = 30) {
23
35
  return (str + " ").substring(0, length);
@@ -60,12 +72,10 @@ function _decode_member_(value: any, field: StructuredTypeField, stream: BinaryS
60
72
  return value;
61
73
  }
62
74
 
63
- type Func1 = (a: any, field: StructuredTypeField, data: ExploreParams, args: any) => void;
64
-
65
- function applyOnAllSchemaFields(self: BaseUAObject, schema: StructuredTypeSchema, data: ExploreParams, functor: Func1, args: any) {
75
+ function _applyOnAllSchemaFields<T>(self: BaseUAObject, schema: IStructuredTypeSchema, data: T, functor: Func1<T>, args?: any) {
66
76
  const baseSchema = get_base_schema(schema);
67
77
  if (baseSchema) {
68
- applyOnAllSchemaFields(self, baseSchema, data, functor, args);
78
+ _applyOnAllSchemaFields(self, baseSchema, data, functor, args);
69
79
  }
70
80
 
71
81
  for (const field of schema.fields) {
@@ -131,7 +141,6 @@ function _exploreObject(self: BaseUAObject, field: StructuredTypeField, data: Ex
131
141
  if (!self) {
132
142
  return;
133
143
  }
134
- assert(self);
135
144
 
136
145
  const fieldType = field.fieldType;
137
146
 
@@ -153,9 +162,10 @@ function _exploreObject(self: BaseUAObject, field: StructuredTypeField, data: Ex
153
162
  if (field.switchValue !== undefined) {
154
163
  opt = " !" + field.switchValue + " ";
155
164
  }
156
-
165
+ const allowSubTypeSymbol = field.allowSubType ? "~" : " ";
166
+ const arraySymbol = field.isArray ? "[]" : " ";
157
167
  const fieldNameF = chalk.yellow(r(padding + fieldName, 30));
158
- const fieldTypeF = chalk.cyan("/* " + r(fieldType + opt, 17) + (field.isArray ? "[]" : " ") + " */");
168
+ const fieldTypeF = chalk.cyan(`/* ${allowSubTypeSymbol}${r(fieldType + opt, 38)}${arraySymbol} */`);
159
169
 
160
170
  // detected when optional field is not specified in value
161
171
  if (field.switchBit !== undefined && value === undefined) {
@@ -297,19 +307,12 @@ function _exploreObject(self: BaseUAObject, field: StructuredTypeField, data: Ex
297
307
  _dump_simple_value(self, field, data, value, fieldType);
298
308
  } else {
299
309
  const typeDictionary = (self.schema as any).$$factory as DataTypeFactory;
310
+
300
311
  // istanbul ignore next
301
312
  if (!typeDictionary) {
302
- // tslint:disable-next-line: no-console
303
- console.log(" No typeDictionary for ", self.schema);
313
+ errorLog("Internal Error: No typeDictionary for ", self.schema);
304
314
  return;
305
315
  }
306
- field.fieldTypeConstructor = field.fieldTypeConstructor || typeDictionary.getStructureTypeConstructor(fieldType);
307
- const fieldTypeConstructor = field.fieldTypeConstructor;
308
-
309
- const _newFieldSchema =
310
- (field.schema as StructuredTypeSchema) ||
311
- fieldTypeConstructor.prototype.schema ||
312
- (fieldTypeConstructor as any).schema;
313
316
 
314
317
  if (field.isArray) {
315
318
  if (value === null) {
@@ -322,13 +325,16 @@ function _exploreObject(self: BaseUAObject, field: StructuredTypeField, data: Ex
322
325
 
323
326
  for (let i = 0; i < m; i++) {
324
327
  const element = value[i];
325
- data.lines.push(padding + chalk.cyan(" { " + ("/*" + i + "*/")));
328
+
329
+ const _newFieldSchema = _findFieldSchema(typeDictionary, field, element);
330
+
331
+ data.lines.push(padding + ` { ` + chalk.cyan(`/* ${i} - ${_newFieldSchema?.name}*/`));
326
332
 
327
333
  const data1 = {
328
334
  lines: [] as string[],
329
335
  padding: padding + " "
330
336
  };
331
- applyOnAllSchemaFields(element, _newFieldSchema, data1, _exploreObject, args);
337
+ _applyOnAllSchemaFields(element, _newFieldSchema, data1, _exploreObject, args);
332
338
 
333
339
  data.lines = data.lines.concat(data1.lines);
334
340
 
@@ -340,9 +346,10 @@ function _exploreObject(self: BaseUAObject, field: StructuredTypeField, data: Ex
340
346
  data.lines.push(padding + "]");
341
347
  }
342
348
  } else {
349
+ const _newFieldSchema = _findFieldSchema(typeDictionary, field, value);
343
350
  data.lines.push(fieldNameF + " " + fieldTypeF + ": {");
344
351
  const data1 = { padding: padding + " ", lines: [] as string[] };
345
- applyOnAllSchemaFields(value, _newFieldSchema, data1, _exploreObject, args);
352
+ _applyOnAllSchemaFields(value, _newFieldSchema, data1, _exploreObject, args);
346
353
  data.lines = data.lines.concat(data1.lines);
347
354
 
348
355
  data.lines.push(padding + "}");
@@ -383,7 +390,7 @@ function json_ify(t: BuiltInTypeDefinition, value: any, fieldType: FieldType) {
383
390
  }
384
391
  }
385
392
 
386
- function _JSONify(self: BaseUAObject, schema: StructuredTypeSchema, pojo: any) {
393
+ function _JSONify(self: BaseUAObject, schema: IStructuredTypeSchema, pojo: any) {
387
394
  /* jshint validthis: true */
388
395
  for (const field of schema.fields) {
389
396
  const fieldValue = (self as any)[field.name];
@@ -391,8 +398,8 @@ function _JSONify(self: BaseUAObject, schema: StructuredTypeSchema, pojo: any) {
391
398
  continue;
392
399
  }
393
400
 
394
- if (hasEnumeration(field.fieldType)) {
395
- const enumeration = getEnumeration(field.fieldType);
401
+ if (hasBuiltInEnumeration(field.fieldType)) {
402
+ const enumeration = getBuiltInEnumeration(field.fieldType);
396
403
  assert(enumeration !== null);
397
404
  if (field.isArray) {
398
405
  pojo[field.name] = fieldValue.map((value: any) => enumeration.enumValues[value.toString()]);
@@ -401,7 +408,7 @@ function _JSONify(self: BaseUAObject, schema: StructuredTypeSchema, pojo: any) {
401
408
  }
402
409
  continue;
403
410
  }
404
- const t = getBuildInType(field.fieldType);
411
+ const t = field.schema as BuiltInTypeDefinition; // getBuiltInType(field.fieldType);
405
412
 
406
413
  if (field.isArray) {
407
414
  pojo[field.name] = fieldValue.map((value: any) => json_ify(t, value, field));
@@ -411,15 +418,8 @@ function _JSONify(self: BaseUAObject, schema: StructuredTypeSchema, pojo: any) {
411
418
  }
412
419
  }
413
420
 
414
- export interface DecodeDebugOptions {
415
- tracer: any;
416
- name: string;
417
- }
418
-
419
- /* tslint:disable:no-empty*/
420
-
421
- export interface BaseUAObject {
422
- schema: StructuredTypeSchema;
421
+ export interface BaseUAObject extends IBaseUAObject {
422
+ schema: IStructuredTypeSchema;
423
423
  }
424
424
 
425
425
  /**
@@ -458,7 +458,7 @@ export class BaseUAObject {
458
458
  */
459
459
  public binaryStoreSize(): number {
460
460
  const stream = new BinaryStreamSizeCalculator();
461
- this.encode(stream as OutputBinaryStream);
461
+ this.encode(stream);
462
462
  return stream.length;
463
463
  }
464
464
 
@@ -548,12 +548,16 @@ export class BaseUAObject {
548
548
 
549
549
  data.lines.push("{" + chalk.cyan(" /*" + (this.schema ? this.schema.name : "") + "*/"));
550
550
  if (this.schema) {
551
- applyOnAllSchemaFields(this, this.schema, data, _exploreObject, arguments);
551
+ this.applyOnAllFields(_exploreObject, data);
552
552
  }
553
553
  data.lines.push("};");
554
554
  return data.lines.join("\n");
555
555
  }
556
556
 
557
+ public applyOnAllFields<T>(func: Func1<T>, data: T): void {
558
+ _applyOnAllSchemaFields(this, this.schema, data, func, null);
559
+ }
560
+
557
561
  public toJSON(): any {
558
562
  assert(this.schema);
559
563
  if (this.schema.toJSON) {
@@ -579,7 +583,7 @@ export class BaseUAObject {
579
583
  continue;
580
584
  }
581
585
  if (field.isArray) {
582
- options[field.name] = self[field.name];
586
+ options[field.name] = [...self[field.name]];
583
587
  } else {
584
588
  options[field.name] = self[field.name];
585
589
  }
@@ -594,9 +598,9 @@ export class BaseUAObject {
594
598
 
595
599
  function _visitSchemaChain(
596
600
  self: BaseUAObject,
597
- schema: StructuredTypeSchema,
601
+ schema: IStructuredTypeSchema,
598
602
  pojo: any,
599
- func: (self: BaseUAObject, schema: StructuredTypeSchema, pojo: any) => void,
603
+ func: (self: BaseUAObject, schema: IStructuredTypeSchema, pojo: any) => void,
600
604
  extraData: any
601
605
  ) {
602
606
  assert(typeof func === "function");
@@ -4,10 +4,10 @@
4
4
  import { assert } from "node-opcua-assert";
5
5
  import { decodeLocaleId, encodeLocaleId, validateLocaleId } from "node-opcua-basic-types";
6
6
  import { BinaryStream, OutputBinaryStream } from "node-opcua-binary-stream";
7
+ import { make_errorLog } from "node-opcua-debug";
8
+ import { getBuiltInType, hasBuiltInType, registerType } from "./builtin_types";
7
9
 
8
- import { findSimpleType, hasBuiltInType, registerType } from "./factories_builtin_types";
9
- import { BasicTypeDefinition, BasicTypeDefinitionOptions } from "./types";
10
-
10
+ const errorLog = make_errorLog("Factory");
11
11
  export interface BasicTypeOptions {
12
12
  name: string;
13
13
  subType: string;
@@ -51,14 +51,13 @@ export function registerBasicType(schema: BasicTypeOptions): void {
51
51
 
52
52
  /* istanbul ignore next */
53
53
  if (exists) {
54
- // tslint:disable-next-line: no-console
55
- console.log("registerBasicType:", schema);
54
+ errorLog("registerBasicType:", schema);
56
55
  throw new Error(`Basic Type ${schema.name} already registered`);
57
56
  }
58
57
 
59
58
  const name = schema.name;
60
59
 
61
- const t: BasicTypeDefinition = findSimpleType(schema.subType);
60
+ const t = getBuiltInType(schema.subType);
62
61
 
63
62
  /* istanbul ignore next */
64
63
  if (!t) {
@@ -86,8 +85,8 @@ export function registerBasicType(schema: BasicTypeOptions): void {
86
85
  subType: schema.subType,
87
86
 
88
87
  coerce: coerceFunc,
89
- decode: decodeFunc,
90
- encode: encodeFunc,
88
+ decode: decodeFunc!,
89
+ encode: encodeFunc!,
91
90
 
92
91
  random,
93
92
 
@@ -105,15 +104,7 @@ export function registerBasicType(schema: BasicTypeOptions): void {
105
104
  registerBasicType({ name: "Counter", subType: "UInt32" });
106
105
  // OPC Unified Architecture, part 3.0 $8.13 page 65
107
106
  registerBasicType({ name: "Duration", subType: "Double" });
108
- registerBasicType({ name: "UAString", subType: "String" });
109
- registerBasicType({ name: "UABoolean", subType: "Boolean" });
110
107
  registerBasicType({ name: "UtcTime", subType: "DateTime" });
111
- // already ? registerBasicType({name: "Int8", subType: "SByte"});
112
- // already ? registerBasicType({name: "UInt8", subType: "Byte"});
113
- registerBasicType({ name: "Char", subType: "Byte" });
114
- // xx registerBasicType({name:"XmlElement" ,subType:"String" });
115
- // xx registerBasicType({ name: "Time", subType: "String" });
116
- // string in the form "en-US" or "de-DE" or "fr" etc...
117
108
 
118
109
  registerBasicType({
119
110
  name: "LocaleId",
@@ -128,8 +119,6 @@ registerBasicType({
128
119
 
129
120
  registerBasicType({ name: "ContinuationPoint", subType: "ByteString" });
130
121
  registerBasicType({ name: "Image", subType: "ByteString" });
131
- registerBasicType({ name: "NodeIdType", subType: "NodeId" });
132
-
133
122
  registerBasicType({ name: "ImageBMP", subType: "Image" });
134
123
  registerBasicType({ name: "ImageGIF", subType: "Image" });
135
124
  registerBasicType({ name: "ImageJPG", subType: "Image" });
@@ -156,13 +145,3 @@ registerBasicType({ name: "Index", subType: "UInt32" });
156
145
  registerBasicType({ name: "VersionTime", subType: "UInt32" });
157
146
  registerBasicType({ name: "ApplicationInstanceCertificate", subType: "ByteString" });
158
147
  registerBasicType({ name: "AttributeWriteMask", subType: "UInt32" });
159
- registerBasicType({ name: "Date", subType: "DateTime" });
160
-
161
- // registerBasicType({ name: "Counter", subType: "UInt32" });
162
- // registerBasicType({ name: "IntegerId", subType: "UInt32" });
163
- // registerBasicType({ name: "UtcTime", subType: "DateTime" });
164
- // registerBasicType({ name: "Duration", subType: "Double" });
165
- // registerBasicType({ name: "LocaleId", subType: "String" });
166
- // registerBasicType({ name: "NumericRange", subType: "String" });
167
- // registerBasicType({ name: "Time", subType: "String" });
168
- // registerBasicType({ name: "SessionAuthenticationToken", subType: "NodeId" });
@@ -13,13 +13,11 @@ import {
13
13
  coerceInt16,
14
14
  coerceInt32,
15
15
  coerceInt64,
16
- coerceInt8,
17
16
  coerceNodeId,
18
17
  coerceSByte,
19
18
  coerceUInt16,
20
19
  coerceUInt32,
21
20
  coerceUInt64,
22
- coerceUInt8,
23
21
  decodeBoolean,
24
22
  decodeByte,
25
23
  decodeByteString,
@@ -31,14 +29,12 @@ import {
31
29
  decodeInt16,
32
30
  decodeInt32,
33
31
  decodeInt64,
34
- decodeInt8,
35
32
  decodeNodeId,
36
33
  decodeSByte,
37
34
  decodeString,
38
35
  decodeUInt16,
39
36
  decodeUInt32,
40
37
  decodeUInt64,
41
- decodeUInt8,
42
38
  encodeBoolean,
43
39
  encodeByte,
44
40
  encodeByteString,
@@ -50,70 +46,106 @@ import {
50
46
  encodeInt16,
51
47
  encodeInt32,
52
48
  encodeInt64,
53
- encodeInt8,
54
49
  encodeNodeId,
55
50
  encodeSByte,
56
51
  encodeString,
57
52
  encodeUInt16,
58
53
  encodeUInt32,
59
54
  encodeUInt64,
60
- encodeUInt8
55
+ minDate
61
56
  } from "node-opcua-basic-types";
62
57
  import { BinaryStream, OutputBinaryStream } from "node-opcua-binary-stream";
58
+ import { DataTypeIds } from "node-opcua-constants";
59
+
63
60
  import { emptyGuid } from "node-opcua-guid";
64
61
  import { makeExpandedNodeId, makeNodeId } from "node-opcua-nodeid";
65
62
  import { coerceStatusCode, decodeStatusCode, encodeStatusCode, StatusCodes } from "node-opcua-status-code";
66
- import { BasicTypeDefinition, BasicTypeDefinitionOptions, FieldCategory, TypeSchemaBase } from "./types";
63
+ import { defaultEncode, defaultDecode, decodeNull, encodeNull, decodeAny, encodeAny, toJSONGuid } from "./encode_decode";
64
+ import { BasicTypeDefinition, BasicTypeDefinitionOptions, BasicTypeDefinitionOptionsBase, CommonInterface, FieldCategory, TypeSchemaConstructorOptions } from "./types";
65
+
67
66
 
68
- // eslint-disable-next-line @typescript-eslint/no-empty-function
69
- function defaultEncode(value: any, stream: OutputBinaryStream): void {}
67
+ /**
68
+ * @class TypeSchemaBase
69
+ * @param options {Object}
70
+ * @constructor
71
+ * create a new type Schema
72
+ */
73
+ export class TypeSchemaBase implements CommonInterface {
74
+ public name: string;
75
+ public defaultValue: any;
76
+ public encode?: (value: any, stream: OutputBinaryStream) => void;
77
+ public decode?: (stream: BinaryStream) => any;
78
+ public coerce?: (value: any) => any;
79
+ public toJSON?: () => string;
80
+ public category: FieldCategory;
81
+ public subType: string;
82
+ public isAbstract: boolean;
83
+
84
+ constructor(options: TypeSchemaConstructorOptions) {
85
+ assert(options.category !== null);
86
+ this.encode = options.encode || undefined;
87
+ this.decode = options.decode || undefined;
88
+ this.coerce = options.coerce;
89
+ this.category = options.category || FieldCategory.basic;
90
+ this.name = options.name;
91
+ for (const prop in options) {
92
+ if (Object.prototype.hasOwnProperty.call(options, prop)) {
93
+ (this as any)[prop] = (options as any)[prop];
94
+ }
95
+ }
96
+ this.subType = options.subType || "";
97
+ this.isAbstract = options.isAbstract || false;
98
+ }
70
99
 
71
- function defaultDecode(stream: BinaryStream): any {
72
- return null;
100
+ /**
101
+ * @method computer_default_value
102
+ * @param defaultValue {*} the default value
103
+ * @return {*}
104
+ */
105
+ public computer_default_value(defaultValue: unknown): any {
106
+ if (defaultValue === undefined) {
107
+ defaultValue = this.defaultValue;
108
+ }
109
+ if (typeof defaultValue === "function") {
110
+ // be careful not to cache this value , it must be call each time to make sure
111
+ // we do not end up with the same value/instance twice.
112
+ defaultValue = defaultValue();
113
+ }
114
+ return defaultValue;
115
+ }
116
+
117
+ public getBaseType(): CommonInterface | null {
118
+ if (!this.subType) return null;
119
+ return getBuiltInType(this.subType) as CommonInterface;
120
+ }
121
+
122
+ public isSubTypeOf(type: CommonInterface): boolean {
123
+ if (this.name === type.name) {
124
+ return true;
125
+ }
126
+ const baseType = this.getBaseType();
127
+ if (!baseType) {
128
+ return false;
129
+ }
130
+ return baseType.isSubTypeOf(type);
131
+ }
73
132
  }
74
133
 
75
134
  export class BasicTypeSchema extends TypeSchemaBase implements BasicTypeDefinition {
76
135
  public subType: string;
77
-
136
+ public isAbstract: boolean;
78
137
  public encode: (value: any, stream: OutputBinaryStream) => void;
79
138
  public decode: (stream: BinaryStream) => any;
80
139
 
81
140
  constructor(options: BasicTypeDefinitionOptions) {
82
141
  super(options);
83
142
  this.subType = options.subType;
143
+ this.isAbstract = options.isAbstract || false;
84
144
  this.encode = options.encode || defaultEncode;
85
145
  this.decode = options.decode || defaultDecode;
86
146
  }
87
147
  }
88
148
 
89
- export const minDate = new Date(Date.UTC(1601, 0, 1, 0, 0, 0));
90
-
91
- function defaultGuidValue(): any {
92
- return Buffer.alloc(0);
93
- }
94
-
95
- function toJSONGuid(value: any): any {
96
- if (typeof value === "string") {
97
- return value;
98
- }
99
- assert(value instanceof Buffer);
100
- return value.toString("base64");
101
- }
102
-
103
- function encodeAny(value: any, stream: OutputBinaryStream) {
104
- assert(false, "type 'Any' cannot be encoded");
105
- }
106
-
107
- function decodeAny(stream: BinaryStream) {
108
- assert(false, "type 'Any' cannot be decoded");
109
- }
110
-
111
- // eslint-disable-next-line @typescript-eslint/no-empty-function
112
- function encodeNull(value: any, stream: OutputBinaryStream): void {}
113
-
114
- function decodeNull(stream: BinaryStream): any {
115
- return null;
116
- }
117
149
 
118
150
  // there are 4 types of DataTypes in opcua:
119
151
  // Built-In DataType
@@ -132,8 +164,9 @@ interface T {
132
164
  defaultValue?: any;
133
165
  toJSON?: any;
134
166
  }
167
+
135
168
  // Built-In Type
136
- const _defaultType: any[] = [
169
+ const _defaultType: BasicTypeDefinitionOptionsBase[] = [
137
170
  // Built-in DataTypes ( see OPCUA Part III v1.02 - $5.8.2 )
138
171
  {
139
172
  name: "Null",
@@ -144,8 +177,8 @@ const _defaultType: any[] = [
144
177
  defaultValue: null
145
178
  },
146
179
  {
180
+ // special case
147
181
  name: "Any",
148
-
149
182
  decode: decodeAny,
150
183
  encode: encodeAny
151
184
  },
@@ -158,17 +191,19 @@ const _defaultType: any[] = [
158
191
  coerce: coerceBoolean,
159
192
  defaultValue: false
160
193
  },
161
- { name: "Int8", encode: encodeInt8, decode: decodeInt8, defaultValue: 0, coerce: coerceInt8 },
162
- { name: "UInt8", encode: encodeUInt8, decode: decodeUInt8, defaultValue: 0, coerce: coerceUInt8 },
163
- { name: "SByte", encode: encodeSByte, decode: decodeSByte, defaultValue: 0, coerce: coerceSByte },
164
- { name: "Byte", encode: encodeByte, decode: decodeByte, defaultValue: 0, coerce: coerceByte },
165
- { name: "Int16", encode: encodeInt16, decode: decodeInt16, defaultValue: 0, coerce: coerceInt16 },
166
- { name: "UInt16", encode: encodeUInt16, decode: decodeUInt16, defaultValue: 0, coerce: coerceUInt16 },
167
- { name: "Int32", encode: encodeInt32, decode: decodeInt32, defaultValue: 0, coerce: coerceInt32 },
168
- { name: "UInt32", encode: encodeUInt32, decode: decodeUInt32, defaultValue: 0, coerce: coerceUInt32 },
194
+
195
+ { name: "Number", isAbstract: true },
196
+ { name: "Integer", subType: "Number", isAbstract: true },
197
+ { name: "UInteger", subType: "Number", isAbstract: true },
198
+ { name: "SByte", subType: "Integer", encode: encodeSByte, decode: decodeSByte, defaultValue: 0, coerce: coerceSByte },
199
+ { name: "Byte", subType: "UInteger", encode: encodeByte, decode: decodeByte, defaultValue: 0, coerce: coerceByte },
200
+ { name: "Int16", subType: "Integer", encode: encodeInt16, decode: decodeInt16, defaultValue: 0, coerce: coerceInt16 },
201
+ { name: "UInt16", subType: "UInteger", encode: encodeUInt16, decode: decodeUInt16, defaultValue: 0, coerce: coerceUInt16 },
202
+ { name: "Int32", subType: "Integer", encode: encodeInt32, decode: decodeInt32, defaultValue: 0, coerce: coerceInt32 },
203
+ { name: "UInt32", subType: "UInteger", encode: encodeUInt32, decode: decodeUInt32, defaultValue: 0, coerce: coerceUInt32 },
169
204
  {
170
205
  name: "Int64",
171
-
206
+ subType: "Integer",
172
207
  decode: decodeInt64,
173
208
  encode: encodeInt64,
174
209
 
@@ -177,7 +212,7 @@ const _defaultType: any[] = [
177
212
  },
178
213
  {
179
214
  name: "UInt64",
180
-
215
+ subType: "UInteger",
181
216
  decode: decodeUInt64,
182
217
  encode: encodeUInt64,
183
218
 
@@ -186,6 +221,7 @@ const _defaultType: any[] = [
186
221
  },
187
222
  {
188
223
  name: "Float",
224
+ subType: "Number",
189
225
 
190
226
  decode: decodeFloat,
191
227
  encode: encodeFloat,
@@ -195,6 +231,7 @@ const _defaultType: any[] = [
195
231
  },
196
232
  {
197
233
  name: "Double",
234
+ subType: "Number",
198
235
 
199
236
  decode: decodeDouble,
200
237
  encode: encodeDouble,
@@ -218,7 +255,7 @@ const _defaultType: any[] = [
218
255
  encode: encodeDateTime,
219
256
 
220
257
  coerce: coerceDateTime,
221
- defaultValue: exports.minDate
258
+ defaultValue: ()=> minDate
222
259
  },
223
260
  {
224
261
  name: "Guid",
@@ -315,18 +352,20 @@ _defaultType.forEach(registerType);
315
352
  * @method registerType
316
353
  * @param schema {TypeSchemaBase}
317
354
  */
318
- export function registerType(schema: BasicTypeDefinitionOptions): void {
319
- assert(typeof schema.name === "string");
320
- if (typeof schema.encode !== "function") {
321
- throw new Error("schema " + schema.name + " has no encode function");
322
- }
323
- if (typeof schema.decode !== "function") {
324
- throw new Error("schema " + schema.name + " has no decode function");
355
+ export function registerType(schema: BasicTypeDefinitionOptionsBase): void {
356
+ if (!schema.isAbstract) {
357
+ assert(schema.encode);
358
+ assert(schema.decode);
325
359
  }
326
-
327
360
  schema.category = FieldCategory.basic;
328
-
329
- const definition = new BasicTypeSchema(schema);
361
+ schema.subType = schema.subType || "";
362
+ if (schema.name !== "Null" && schema.name !== "Any" && schema.name !== "Variant" && schema.name !== "ExtensionObject") {
363
+ const dataType = DataTypeIds[schema.name as keyof typeof DataTypeIds];
364
+ if (!dataType) {
365
+ throw new Error("registerType : dataType " + schema.name + " is not defined");
366
+ }
367
+ }
368
+ const definition = new BasicTypeSchema(schema as BasicTypeDefinitionOptions);
330
369
  _defaultTypeMap.set(schema.name, definition);
331
370
  }
332
371
 
@@ -336,46 +375,29 @@ export function unregisterType(typeName: string): void {
336
375
  _defaultTypeMap.delete(typeName);
337
376
  }
338
377
 
339
- /**
340
- * @method findSimpleType
341
- * @param name
342
- * @return {TypeSchemaBase|null}
343
- */
344
- export function findSimpleType(name: string): BasicTypeDefinition {
378
+ export function getBuiltInType(name: string): TypeSchemaBase {
345
379
  const typeSchema = _defaultTypeMap.get(name);
346
380
  if (!typeSchema) {
347
381
  throw new Error("Cannot find schema for simple type " + name);
348
382
  }
349
- assert(typeSchema instanceof TypeSchemaBase);
350
- return typeSchema as BasicTypeDefinition;
383
+ return typeSchema;
351
384
  }
352
385
 
353
386
  export function hasBuiltInType(name: string): boolean {
354
387
  return _defaultTypeMap.has(name);
355
388
  }
356
389
 
357
- export function getBuildInType(name: string): BasicTypeDefinition {
358
- return _defaultTypeMap.get(name) as BasicTypeDefinition;
359
- }
360
-
361
- /**
362
- * @method findBuiltInType
363
- * find the Builtin Type that this
364
- * @param dataTypeName
365
- * @return {*}
366
- */
390
+ /** */
367
391
  export function findBuiltInType(dataTypeName: string): BasicTypeDefinition {
368
392
  assert(typeof dataTypeName === "string", "findBuiltInType : expecting a string " + dataTypeName);
369
- const t = _defaultTypeMap.get(dataTypeName) as BasicTypeDefinition;
370
- if (!t) {
371
- throw new Error("datatype " + dataTypeName + " must be registered");
372
- }
393
+ const t = getBuiltInType(dataTypeName);
373
394
  if (t.subType && t.subType !== t.name /* avoid infinite recursion */) {
374
- return findBuiltInType(t.subType);
395
+ const st = getBuiltInType(t.subType);
396
+ if (!st.isAbstract) {
397
+ return findBuiltInType(t.subType);
398
+ }
375
399
  }
376
400
  return t;
377
401
  }
378
402
 
379
- export function getTypeMap(): Map<string, BasicTypeSchema> {
380
- return _defaultTypeMap;
381
- }
403
+