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.
- package/dist/base_ua_object.d.ts +53 -0
- package/dist/base_ua_object.js +536 -0
- package/dist/base_ua_object.js.map +1 -0
- package/dist/basic_type.d.ts +40 -0
- package/dist/basic_type.js +119 -0
- package/dist/basic_type.js.map +1 -0
- package/dist/builtin_types.d.ts +46 -0
- package/dist/builtin_types.js +284 -0
- package/dist/builtin_types.js.map +1 -0
- package/dist/builtin_types_special.d.ts +5 -0
- package/dist/builtin_types_special.js +46 -0
- package/dist/builtin_types_special.js.map +1 -0
- package/dist/constructor_type.d.ts +15 -15
- package/dist/constructor_type.js +2 -2
- package/dist/datatype_factory.d.ts +36 -39
- package/dist/datatype_factory.js +305 -322
- package/dist/datatype_factory.js.map +1 -1
- package/dist/encode_decode.d.ts +9 -0
- package/dist/encode_decode.js +40 -0
- package/dist/encode_decode.js.map +1 -0
- package/dist/enumerations.d.ts +32 -0
- package/dist/enumerations.js +78 -0
- package/dist/enumerations.js.map +1 -0
- package/dist/factories_baseobject.d.ts +56 -56
- package/dist/factories_baseobject.js +534 -534
- package/dist/factories_basic_type.d.ts +40 -40
- package/dist/factories_basic_type.js +135 -135
- package/dist/factories_builtin_types.d.ts +32 -32
- package/dist/factories_builtin_types.js +261 -261
- package/dist/factories_builtin_types_special.d.ts +5 -5
- package/dist/factories_builtin_types_special.js +45 -45
- package/dist/factories_enumerations.d.ts +31 -31
- package/dist/factories_enumerations.js +77 -77
- package/dist/factories_factories.d.ts +17 -17
- package/dist/factories_factories.js +53 -53
- package/dist/factories_id_generator.d.ts +3 -3
- package/dist/factories_id_generator.js +21 -21
- package/dist/factories_schema_helpers.d.ts +27 -27
- package/dist/factories_schema_helpers.js +121 -121
- package/dist/factories_structuredTypeSchema.d.ts +45 -45
- package/dist/factories_structuredTypeSchema.js +276 -276
- package/dist/get_built_in_type.d.ts +0 -0
- package/dist/get_built_in_type.js +2 -0
- package/dist/get_built_in_type.js.map +1 -0
- package/dist/get_standard_data_type_factory.d.ts +12 -0
- package/dist/get_standard_data_type_factory.js +35 -0
- package/dist/get_standard_data_type_factory.js.map +1 -0
- package/dist/get_structured_type_schema.d.ts +4 -0
- package/dist/get_structured_type_schema.js +13 -0
- package/dist/get_structured_type_schema.js.map +1 -0
- package/dist/id_generator.d.ts +3 -0
- package/dist/id_generator.js +22 -0
- package/dist/id_generator.js.map +1 -0
- package/dist/index.d.ts +18 -15
- package/dist/index.js +34 -31
- package/dist/index.js.map +1 -1
- package/dist/nodeid_type.d.ts +13 -0
- package/dist/nodeid_type.js +19 -0
- package/dist/nodeid_type.js.map +1 -0
- package/dist/parameters.d.ts +3 -0
- package/dist/parameters.js +7 -0
- package/dist/parameters.js.map +1 -0
- package/dist/register_class_definition.d.ts +3 -0
- package/dist/register_class_definition.js +9 -0
- package/dist/register_class_definition.js.map +1 -0
- package/dist/schema_helpers.d.ts +24 -0
- package/dist/schema_helpers.js +100 -0
- package/dist/schema_helpers.js.map +1 -0
- package/dist/structured_type_schema.d.ts +44 -0
- package/dist/structured_type_schema.js +279 -0
- package/dist/structured_type_schema.js.map +1 -0
- package/dist/types.d.ts +151 -110
- package/dist/types.js +9 -51
- package/dist/types.js.map +1 -1
- package/package.json +7 -6
- package/source/{factories_baseobject.ts → base_ua_object.ts} +48 -44
- package/source/{factories_basic_type.ts → basic_type.ts} +7 -28
- package/source/{factories_builtin_types.ts → builtin_types.ts} +111 -89
- package/source/{factories_builtin_types_special.ts → builtin_types_special.ts} +2 -2
- package/source/datatype_factory.ts +44 -47
- package/source/encode_decode.ts +37 -0
- package/source/{factories_enumerations.ts → enumerations.ts} +6 -4
- package/source/get_built_in_type.ts +0 -0
- package/source/{factories_factories.ts → get_standard_data_type_factory.ts} +7 -25
- package/source/get_structured_type_schema.ts +10 -0
- package/source/{factories_id_generator.ts → id_generator.ts} +0 -0
- package/source/index.ts +14 -11
- package/source/nodeid_type.ts +17 -0
- package/source/parameters.ts +3 -0
- package/source/register_class_definition.ts +11 -0
- package/source/{factories_schema_helpers.ts → schema_helpers.ts} +15 -37
- package/source/{factories_structuredTypeSchema.ts → structured_type_schema.ts} +37 -36
- package/source/types.ts +104 -79
- 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.
|
|
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": "
|
|
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.
|
|
18
|
-
"node-opcua-binary-stream": "2.
|
|
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.
|
|
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": "
|
|
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 {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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 (
|
|
395
|
-
const enumeration =
|
|
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 =
|
|
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
|
|
415
|
-
|
|
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
|
|
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
|
-
|
|
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:
|
|
601
|
+
schema: IStructuredTypeSchema,
|
|
598
602
|
pojo: any,
|
|
599
|
-
func: (self: BaseUAObject, schema:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
69
|
-
|
|
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
|
-
|
|
72
|
-
|
|
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:
|
|
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
|
-
|
|
162
|
-
{ name: "
|
|
163
|
-
{ name: "
|
|
164
|
-
{ name: "
|
|
165
|
-
{ name: "
|
|
166
|
-
{ name: "
|
|
167
|
-
{ name: "
|
|
168
|
-
{ name: "
|
|
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:
|
|
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:
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
380
|
-
return _defaultTypeMap;
|
|
381
|
-
}
|
|
403
|
+
|