node-opcua-factory 2.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/LICENSE +20 -0
  2. package/dist/constructor_type.d.ts +15 -0
  3. package/dist/constructor_type.js +3 -0
  4. package/dist/constructor_type.js.map +1 -0
  5. package/dist/datatype_factory.d.ts +40 -0
  6. package/dist/datatype_factory.js +330 -0
  7. package/dist/datatype_factory.js.map +1 -0
  8. package/dist/factories_baseobject.d.ts +56 -0
  9. package/dist/factories_baseobject.js +498 -0
  10. package/dist/factories_baseobject.js.map +1 -0
  11. package/dist/factories_basic_type.d.ts +40 -0
  12. package/dist/factories_basic_type.js +136 -0
  13. package/dist/factories_basic_type.js.map +1 -0
  14. package/dist/factories_builtin_types.d.ts +32 -0
  15. package/dist/factories_builtin_types.js +262 -0
  16. package/dist/factories_builtin_types.js.map +1 -0
  17. package/dist/factories_builtin_types_special.d.ts +5 -0
  18. package/dist/factories_builtin_types_special.js +46 -0
  19. package/dist/factories_builtin_types_special.js.map +1 -0
  20. package/dist/factories_enumerations.d.ts +31 -0
  21. package/dist/factories_enumerations.js +77 -0
  22. package/dist/factories_enumerations.js.map +1 -0
  23. package/dist/factories_factories.d.ts +17 -0
  24. package/dist/factories_factories.js +54 -0
  25. package/dist/factories_factories.js.map +1 -0
  26. package/dist/factories_id_generator.d.ts +3 -0
  27. package/dist/factories_id_generator.js +22 -0
  28. package/dist/factories_id_generator.js.map +1 -0
  29. package/dist/factories_schema_helpers.d.ts +26 -0
  30. package/dist/factories_schema_helpers.js +121 -0
  31. package/dist/factories_schema_helpers.js.map +1 -0
  32. package/dist/factories_structuredTypeSchema.d.ts +46 -0
  33. package/dist/factories_structuredTypeSchema.js +269 -0
  34. package/dist/factories_structuredTypeSchema.js.map +1 -0
  35. package/dist/index.d.ts +15 -0
  36. package/dist/index.js +28 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/types.d.ts +111 -0
  39. package/dist/types.js +56 -0
  40. package/dist/types.js.map +1 -0
  41. package/package.json +41 -0
  42. package/source/constructor_type.ts +18 -0
  43. package/source/datatype_factory.ts +368 -0
  44. package/source/factories_baseobject.ts +567 -0
  45. package/source/factories_basic_type.ts +168 -0
  46. package/source/factories_builtin_types.ts +381 -0
  47. package/source/factories_builtin_types_special.ts +55 -0
  48. package/source/factories_enumerations.ts +97 -0
  49. package/source/factories_factories.ts +58 -0
  50. package/source/factories_id_generator.ts +18 -0
  51. package/source/factories_schema_helpers.ts +125 -0
  52. package/source/factories_structuredTypeSchema.ts +330 -0
  53. package/source/index.ts +15 -0
  54. package/source/types.ts +180 -0
@@ -0,0 +1,168 @@
1
+ /**
2
+ * @module node-opcua-factory
3
+ */
4
+ import { assert } from "node-opcua-assert";
5
+ import { decodeLocaleId, encodeLocaleId, validateLocaleId } from "node-opcua-basic-types";
6
+ import { BinaryStream, OutputBinaryStream } from "node-opcua-binary-stream";
7
+
8
+ import { findSimpleType, hasBuiltInType, registerType } from "./factories_builtin_types";
9
+ import { BasicTypeDefinition, BasicTypeDefinitionOptions } from "./types";
10
+
11
+ export interface BasicTypeOptions {
12
+ name: string;
13
+ subType: string;
14
+ encode?: (value: any, stream: OutputBinaryStream) => void;
15
+ decode?: (stream: BinaryStream) => void;
16
+ validate?: (value: any) => boolean;
17
+ coerce?: (value: any) => any;
18
+ toJSON?: (value: any) => any;
19
+ random?: () => any;
20
+ defaultValue?: any;
21
+ }
22
+ /**
23
+ * register a Basic Type ,
24
+ * A basic type is new entity type that resolved to a SubType
25
+ * @example:
26
+ *
27
+ *
28
+ * registerBasicType({name:"Duration" ,subType:"Double"});
29
+ *
30
+ * @method registerBasicType
31
+ * @param schema
32
+ * @param schema.name {String}
33
+ * @param schema.subType {String} mandatory, the basic type from which the new type derives.
34
+ *
35
+ * @param [schema.encode] {Function} optional,a specific encoder function to encode an instance of this type.
36
+ * @param schema.encode.value {*}
37
+ * @param schema.encode.stream {BinaryStream}
38
+ *
39
+ * @param [schema.decode] optional,a specific decoder function that returns the decode value out of the stream.
40
+ * @param [schema.decode.stream] {BinaryStream}
41
+ *
42
+ * @param [schema.coerce] optional, a method to convert a value into the request type.
43
+ * @param schema.coerce.value {*} the value to coerce.
44
+ *
45
+ * @param [schema.random] optional, a method to construct a random object of this type
46
+ *
47
+ * @param [schema.toJSON]optional, a method to convert a value into the request type.
48
+ */
49
+ export function registerBasicType(schema: BasicTypeOptions) {
50
+ const exists: boolean = hasBuiltInType(schema.name);
51
+
52
+ /* istanbul ignore next */
53
+ if (exists) {
54
+ // tslint:disable-next-line: no-console
55
+ console.log("registerBasicType:", schema);
56
+ throw new Error(`Basic Type ${schema.name} already registered`);
57
+ }
58
+
59
+ const name = schema.name;
60
+
61
+ const t: BasicTypeDefinition = findSimpleType(schema.subType);
62
+
63
+ /* istanbul ignore next */
64
+ if (!t) {
65
+ // tslint:disable-next-line:no-console
66
+ throw new Error(" cannot find subtype " + schema.subType);
67
+ }
68
+ assert(typeof t.decode === "function");
69
+
70
+ const encodeFunc = schema.encode || t.encode;
71
+ assert(typeof encodeFunc === "function");
72
+
73
+ const decodeFunc = schema.decode || t.decode;
74
+ assert(typeof decodeFunc === "function");
75
+
76
+ const defaultValue = schema.defaultValue === undefined ? t.defaultValue : schema.defaultValue;
77
+ // assert(typeof defaultValue === "function");
78
+
79
+ const coerceFunc = schema.coerce || t.coerce;
80
+ const toJSONFunc = schema.toJSON || t.toJSON;
81
+ const random = schema.random || defaultValue;
82
+
83
+ const newSchema = {
84
+ name,
85
+
86
+ subType: schema.subType,
87
+
88
+ coerce: coerceFunc,
89
+ decode: decodeFunc,
90
+ encode: encodeFunc,
91
+
92
+ random,
93
+
94
+ defaultValue,
95
+
96
+ toJSON: toJSONFunc
97
+ };
98
+ registerType(newSchema);
99
+ }
100
+
101
+ // =============================================================================================
102
+ // Registering the Basic Type already defined int the OPC-UA Specification
103
+ // =============================================================================================
104
+
105
+ registerBasicType({ name: "Counter", subType: "UInt32" });
106
+ // OPC Unified Architecture, part 3.0 $8.13 page 65
107
+ registerBasicType({ name: "Duration", subType: "Double" });
108
+ registerBasicType({ name: "UAString", subType: "String" });
109
+ registerBasicType({ name: "UABoolean", subType: "Boolean" });
110
+ 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
+
118
+ registerBasicType({
119
+ name: "LocaleId",
120
+ subType: "String",
121
+
122
+ defaultValue: null,
123
+
124
+ decode: decodeLocaleId,
125
+ encode: encodeLocaleId,
126
+ validate: validateLocaleId
127
+ });
128
+
129
+ registerBasicType({ name: "ContinuationPoint", subType: "ByteString" });
130
+ registerBasicType({ name: "Image", subType: "ByteString" });
131
+ registerBasicType({ name: "NodeIdType", subType: "NodeId" });
132
+
133
+ registerBasicType({ name: "ImageBMP", subType: "Image" });
134
+ registerBasicType({ name: "ImageGIF", subType: "Image" });
135
+ registerBasicType({ name: "ImageJPG", subType: "Image" });
136
+ registerBasicType({ name: "ImagePNG", subType: "Image" });
137
+ registerBasicType({ name: "AudioDataType", subType: "ByteString" });
138
+ registerBasicType({ name: "BitFieldMaskDataType", subType: "UInt64" });
139
+ registerBasicType({ name: "DataSetFieldFlags", subType: "UInt16" });
140
+ registerBasicType({ name: "DataSetFieldContentMask", subType: "UInt32" });
141
+ registerBasicType({ name: "UadpNetworkMessageContentMask", subType: "UInt32" });
142
+ registerBasicType({ name: "UadpDataSetMessageContentMask", subType: "UInt32" });
143
+ registerBasicType({ name: "JsonNetworkMessageContentMask", subType: "UInt32" });
144
+ registerBasicType({ name: "JsonDataSetMessageContentMask", subType: "UInt32" });
145
+ registerBasicType({ name: "PermissionType", subType: "UInt32" });
146
+ registerBasicType({ name: "AccessLevelType", subType: "Byte" });
147
+ registerBasicType({ name: "AccessLevelExType", subType: "UInt32" });
148
+ registerBasicType({ name: "EventNotifierType", subType: "Byte" });
149
+ registerBasicType({ name: "AccessRestrictionType", subType: "UInt32" });
150
+ registerBasicType({ name: "NormalizedString", subType: "String" });
151
+ registerBasicType({ name: "DecimalString", subType: "String" });
152
+ registerBasicType({ name: "DurationString", subType: "String" });
153
+ registerBasicType({ name: "TimeString", subType: "String" });
154
+ registerBasicType({ name: "DateString", subType: "String" });
155
+ registerBasicType({ name: "Index", subType: "UInt32" });
156
+ registerBasicType({ name: "VersionTime", subType: "UInt32" });
157
+ registerBasicType({ name: "ApplicationInstanceCertificate", subType: "ByteString" });
158
+ 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" });
@@ -0,0 +1,381 @@
1
+ /**
2
+ * @module node-opcua-factory
3
+ */
4
+ import { assert } from "node-opcua-assert";
5
+ import {
6
+ coerceBoolean,
7
+ coerceByte,
8
+ coerceByteString,
9
+ coerceDateTime,
10
+ coerceDouble,
11
+ coerceExpandedNodeId,
12
+ coerceFloat,
13
+ coerceInt16,
14
+ coerceInt32,
15
+ coerceInt64,
16
+ coerceInt8,
17
+ coerceNodeId,
18
+ coerceSByte,
19
+ coerceUInt16,
20
+ coerceUInt32,
21
+ coerceUInt64,
22
+ coerceUInt8,
23
+ decodeBoolean,
24
+ decodeByte,
25
+ decodeByteString,
26
+ decodeDateTime,
27
+ decodeDouble,
28
+ decodeExpandedNodeId,
29
+ decodeFloat,
30
+ decodeGuid,
31
+ decodeInt16,
32
+ decodeInt32,
33
+ decodeInt64,
34
+ decodeInt8,
35
+ decodeNodeId,
36
+ decodeSByte,
37
+ decodeString,
38
+ decodeUInt16,
39
+ decodeUInt32,
40
+ decodeUInt64,
41
+ decodeUInt8,
42
+ encodeBoolean,
43
+ encodeByte,
44
+ encodeByteString,
45
+ encodeDateTime,
46
+ encodeDouble,
47
+ encodeExpandedNodeId,
48
+ encodeFloat,
49
+ encodeGuid,
50
+ encodeInt16,
51
+ encodeInt32,
52
+ encodeInt64,
53
+ encodeInt8,
54
+ encodeNodeId,
55
+ encodeSByte,
56
+ encodeString,
57
+ encodeUInt16,
58
+ encodeUInt32,
59
+ encodeUInt64,
60
+ encodeUInt8
61
+ } from "node-opcua-basic-types";
62
+ import { BinaryStream, OutputBinaryStream } from "node-opcua-binary-stream";
63
+ import { emptyGuid } from "node-opcua-guid";
64
+ import { makeExpandedNodeId, makeNodeId } from "node-opcua-nodeid";
65
+ import { coerceStatusCode, decodeStatusCode, encodeStatusCode, StatusCodes } from "node-opcua-status-code";
66
+ import { BasicTypeDefinition, BasicTypeDefinitionOptions, FieldCategory, TypeSchemaBase } from "./types";
67
+
68
+ // tslint:disable:no-empty
69
+ // tslint:enable:no-unused-variable
70
+ function defaultEncode(value: any, stream: OutputBinaryStream): void {}
71
+
72
+ function defaultDecode(stream: BinaryStream): any {
73
+ return null;
74
+ }
75
+
76
+ export class BasicTypeSchema extends TypeSchemaBase implements BasicTypeDefinition {
77
+ public subType: string;
78
+
79
+ public encode: (value: any, stream: OutputBinaryStream) => void;
80
+ public decode: (stream: BinaryStream) => any;
81
+
82
+ constructor(options: BasicTypeDefinitionOptions) {
83
+ super(options);
84
+ this.subType = options.subType;
85
+ this.encode = options.encode || defaultEncode;
86
+ this.decode = options.decode || defaultDecode;
87
+ }
88
+ }
89
+
90
+ export const minDate = new Date(Date.UTC(1601, 0, 1, 0, 0, 0));
91
+
92
+ function defaultGuidValue(): any {
93
+ return Buffer.alloc(0);
94
+ }
95
+
96
+ function toJSONGuid(value: any): any {
97
+ if (typeof value === "string") {
98
+ return value;
99
+ }
100
+ assert(value instanceof Buffer);
101
+ return value.toString("base64");
102
+ }
103
+
104
+ function encodeAny(value: any, stream: OutputBinaryStream) {
105
+ assert(false, "type 'Any' cannot be encoded");
106
+ }
107
+
108
+ function decodeAny(stream: BinaryStream) {
109
+ assert(false, "type 'Any' cannot be decoded");
110
+ }
111
+
112
+ function encodeNull(value: any, stream: OutputBinaryStream): void {}
113
+
114
+ function decodeNull(stream: BinaryStream): any {
115
+ return null;
116
+ }
117
+
118
+ // there are 4 types of DataTypes in opcua:
119
+ // Built-In DataType
120
+ // Simple DataType
121
+ // Complex DataType
122
+ // Enumeration
123
+
124
+ const defaultXmlElement = "";
125
+
126
+ interface T {
127
+ subType?: any;
128
+ name: string;
129
+ encode: (value: any, stream: OutputBinaryStream) => void;
130
+ decode: (stream: BinaryStream) => any;
131
+ coerce?: any;
132
+ defaultValue?: any;
133
+ toJSON?: any;
134
+ }
135
+ // Built-In Type
136
+ const _defaultType: any[] = [
137
+ // Built-in DataTypes ( see OPCUA Part III v1.02 - $5.8.2 )
138
+ {
139
+ name: "Null",
140
+
141
+ decode: decodeNull,
142
+ encode: encodeNull,
143
+
144
+ defaultValue: null
145
+ },
146
+ {
147
+ name: "Any",
148
+
149
+ decode: decodeAny,
150
+ encode: encodeAny
151
+ },
152
+ {
153
+ name: "Boolean",
154
+
155
+ decode: decodeBoolean,
156
+ encode: encodeBoolean,
157
+
158
+ coerce: coerceBoolean,
159
+ defaultValue: false
160
+ },
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 },
169
+ {
170
+ name: "Int64",
171
+
172
+ decode: decodeInt64,
173
+ encode: encodeInt64,
174
+
175
+ coerce: coerceInt64,
176
+ defaultValue: coerceInt64(0)
177
+ },
178
+ {
179
+ name: "UInt64",
180
+
181
+ decode: decodeUInt64,
182
+ encode: encodeUInt64,
183
+
184
+ coerce: coerceUInt64,
185
+ defaultValue: coerceUInt64(0)
186
+ },
187
+ {
188
+ name: "Float",
189
+
190
+ decode: decodeFloat,
191
+ encode: encodeFloat,
192
+
193
+ coerce: coerceFloat,
194
+ defaultValue: 0.0
195
+ },
196
+ {
197
+ name: "Double",
198
+
199
+ decode: decodeDouble,
200
+ encode: encodeDouble,
201
+
202
+ coerce: coerceDouble,
203
+ defaultValue: 0.0
204
+ },
205
+ {
206
+ name: "String",
207
+
208
+ decode: decodeString,
209
+ encode: encodeString,
210
+
211
+ defaultValue: ""
212
+ },
213
+ // OPC Unified Architecture, part 3.0 $8.26 page 67
214
+ {
215
+ name: "DateTime",
216
+
217
+ decode: decodeDateTime,
218
+ encode: encodeDateTime,
219
+
220
+ coerce: coerceDateTime,
221
+ defaultValue: exports.minDate
222
+ },
223
+ {
224
+ name: "Guid",
225
+
226
+ decode: decodeGuid,
227
+ encode: encodeGuid,
228
+
229
+ defaultValue: emptyGuid
230
+ },
231
+
232
+ {
233
+ name: "ByteString",
234
+
235
+ decode: decodeByteString,
236
+ encode: encodeByteString,
237
+
238
+ coerce: coerceByteString,
239
+ defaultValue: null,
240
+ toJSON: toJSONGuid
241
+ },
242
+ {
243
+ name: "XmlElement",
244
+
245
+ decode: decodeString,
246
+ encode: encodeString,
247
+
248
+ defaultValue: defaultXmlElement
249
+ },
250
+
251
+ // see OPCUA Part 3 - V1.02 $8.2.1
252
+ {
253
+ name: "NodeId",
254
+
255
+ decode: decodeNodeId,
256
+ encode: encodeNodeId,
257
+
258
+ coerce: coerceNodeId,
259
+ defaultValue: makeNodeId
260
+ },
261
+ {
262
+ name: "ExpandedNodeId",
263
+
264
+ decode: decodeExpandedNodeId,
265
+ encode: encodeExpandedNodeId,
266
+
267
+ coerce: coerceExpandedNodeId,
268
+ defaultValue: makeExpandedNodeId
269
+ },
270
+
271
+ // ----------------------------------------------------------------------------------------
272
+ // Simple DataTypes
273
+ // ( see OPCUA Part III v1.02 - $5.8.2 )
274
+ // Simple DataTypes are subtypes of the Built-in DataTypes. They are handled on the wire like the
275
+ // Built-in DataType, i.e. they cannot be distinguished on the wire from their Built-in supertypes.
276
+ // Since they are handled like Built-in DataTypes regarding the encoding they cannot have encodings
277
+ // defined in the AddressSpace. Clients can read the DataType Attribute of a Variable or VariableType to
278
+ // identify the Simple DataType of the Value Attribute. An example of a Simple DataType is Duration. It
279
+ // is handled on the wire as a Double but the Client can read the DataType Attribute and thus interpret
280
+ // the value as defined by Duration
281
+ //
282
+
283
+ // OPC Unified Architecture, part 4.0 $7.13
284
+ // IntegerID: This primitive data type is an UInt32 that is used as an identifier, such as a handle. All values,
285
+ // except for 0, are valid.
286
+ {
287
+ name: "IntegerId",
288
+
289
+ decode: decodeUInt32,
290
+ encode: encodeUInt32,
291
+
292
+ defaultValue: 0xffffffff
293
+ },
294
+
295
+ // The StatusCode is a 32-bit unsigned integer. The top 16 bits represent the numeric value of the
296
+ // code that shall be used for detecting specific errors or conditions. The bottom 16 bits are bit flags
297
+ // that contain additional information but do not affect the meaning of the StatusCode.
298
+ // 7.33 Part 4 - P 143
299
+ {
300
+ name: "StatusCode",
301
+
302
+ decode: decodeStatusCode,
303
+ encode: encodeStatusCode,
304
+
305
+ coerce: coerceStatusCode,
306
+ defaultValue: StatusCodes.Good
307
+ }
308
+ ];
309
+
310
+ /**
311
+ * @method registerType
312
+ * @param schema {TypeSchemaBase}
313
+ */
314
+ export function registerType(schema: BasicTypeDefinitionOptions): void {
315
+ assert(typeof schema.name === "string");
316
+ if (typeof schema.encode !== "function") {
317
+ throw new Error("schema " + schema.name + " has no encode function");
318
+ }
319
+ if (typeof schema.decode !== "function") {
320
+ throw new Error("schema " + schema.name + " has no decode function");
321
+ }
322
+
323
+ schema.category = FieldCategory.basic;
324
+
325
+ const definition = new BasicTypeSchema(schema);
326
+ _defaultTypeMap.set(schema.name, definition);
327
+ }
328
+
329
+ export const registerBuiltInType = registerType;
330
+
331
+ export function unregisterType(typeName: string): void {
332
+ _defaultTypeMap.delete(typeName);
333
+ }
334
+
335
+ /**
336
+ * @method findSimpleType
337
+ * @param name
338
+ * @return {TypeSchemaBase|null}
339
+ */
340
+ export function findSimpleType(name: string): BasicTypeDefinition {
341
+ const typeSchema = _defaultTypeMap.get(name);
342
+ if (!typeSchema) {
343
+ throw new Error("Cannot find schema for simple type " + name);
344
+ }
345
+ assert(typeSchema instanceof TypeSchemaBase);
346
+ return typeSchema as BasicTypeDefinition;
347
+ }
348
+
349
+ // populate the default type map
350
+ const _defaultTypeMap: Map<string, BasicTypeSchema> = new Map<string, BasicTypeSchema>();
351
+ _defaultType.forEach(registerType);
352
+
353
+ export function hasBuiltInType(name: string): boolean {
354
+ return _defaultTypeMap.has(name);
355
+ }
356
+
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
+ */
367
+ export function findBuiltInType(dataTypeName: string): BasicTypeDefinition {
368
+ 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
+ }
373
+ if (t.subType && t.subType !== t.name /* avoid infinite recursion */) {
374
+ return findBuiltInType(t.subType);
375
+ }
376
+ return t;
377
+ }
378
+
379
+ export function getTypeMap() {
380
+ return _defaultTypeMap;
381
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @module node-opcua-factory
3
+ */
4
+
5
+ import { assert } from "node-opcua-assert";
6
+ import { BinaryStream, OutputBinaryStream } from "node-opcua-binary-stream";
7
+
8
+ import { registerType } from "./factories_builtin_types";
9
+ import { ConstructorFunc } from "./constructor_type";
10
+
11
+ function _self_encode(constructor: any) {
12
+ assert(typeof constructor === "function");
13
+ return (value: any, stream: OutputBinaryStream) => {
14
+ if (!value || !value.encode) {
15
+ value = new constructor(value);
16
+ }
17
+ value.encode(stream);
18
+ };
19
+ }
20
+
21
+ function _self_decode(constructor: any) {
22
+ assert(typeof constructor === "function");
23
+ return (stream: BinaryStream) => {
24
+ const value = new constructor();
25
+ value.decode(stream);
26
+ return value;
27
+ };
28
+ }
29
+
30
+ function _self_coerce(constructor: any) {
31
+ assert(typeof constructor === "function");
32
+ return (value: any) => {
33
+ const obj = new constructor(value);
34
+ return obj;
35
+ };
36
+ }
37
+
38
+ export function registerSpecialVariantEncoder(constructor: ConstructorFunc) {
39
+ assert(typeof constructor === "function");
40
+
41
+ const name = constructor.prototype.schema.name;
42
+
43
+ registerType({
44
+ name,
45
+ subType: name,
46
+
47
+ encode: _self_encode(constructor),
48
+
49
+ decode: _self_decode(constructor),
50
+
51
+ coerce: _self_coerce(constructor),
52
+
53
+ defaultValue: () => new constructor()
54
+ });
55
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * @module node-opcua-factory
3
+ */
4
+ import { assert } from "node-opcua-assert";
5
+
6
+ import { BinaryStream, OutputBinaryStream } from "node-opcua-binary-stream";
7
+ import { Enum, EnumItem } from "node-opcua-enum";
8
+ import { EnumerationDefinition, TypeSchemaBase, TypeSchemaConstructorOptions } from "./types";
9
+
10
+ function _encode_enumeration(typedEnum: Enum, value: number, stream: OutputBinaryStream): void {
11
+ assert(typeof value === "number", "Expecting a number here");
12
+ assert(typedEnum.get(value) !== undefined, "expecting a valid value");
13
+ stream.writeInteger(value);
14
+ }
15
+
16
+ function _decode_enumeration(typedEnum: Enum, stream: BinaryStream): number {
17
+ const value = stream.readInteger();
18
+ const e = (typedEnum.get(value) as any) as string;
19
+ // istanbul ignore next
20
+ if (!e) {
21
+ throw new Error("cannot coerce value=" + value + " to " + typedEnum.constructor.name);
22
+ }
23
+ return value;
24
+ }
25
+
26
+ export interface EnumerationDefinitionOptions extends TypeSchemaConstructorOptions {
27
+ enumValues: any;
28
+ typedEnum?: any;
29
+ lengthInBits?: number;
30
+
31
+ // specialized methods
32
+ defaultValue?: EnumItem;
33
+ encode?: (value: EnumItem, stream: OutputBinaryStream) => void;
34
+ decode?: (stream: BinaryStream) => EnumItem;
35
+ }
36
+
37
+ export class EnumerationDefinitionSchema extends TypeSchemaBase implements EnumerationDefinition {
38
+ public enumValues: any;
39
+ public typedEnum: Enum;
40
+ public lengthInBits: number;
41
+ // xx encode: (value: EnumItem, stream: OutputBinaryStream) => void;
42
+ // xx decode: (stream: BinaryStream) => EnumItem;
43
+
44
+ constructor(options: EnumerationDefinitionOptions) {
45
+ super(options);
46
+ // create a new Enum
47
+ const typedEnum = new Enum(options.enumValues);
48
+ options.typedEnum = typedEnum;
49
+
50
+ assert(!options.encode || typeof options.encode === "function");
51
+ assert(!options.decode || typeof options.decode === "function");
52
+ this.encode = options.encode || _encode_enumeration.bind(null, typedEnum);
53
+ this.decode = options.decode || _decode_enumeration.bind(null, typedEnum);
54
+
55
+ this.typedEnum = options.typedEnum;
56
+ this.defaultValue = this.typedEnum.getDefaultValue().value;
57
+ this.lengthInBits = options.lengthInBits || 32;
58
+ }
59
+ }
60
+
61
+ const _enumerations: Map<string, EnumerationDefinitionSchema> = new Map<string, EnumerationDefinitionSchema>();
62
+
63
+ /**
64
+ * @method registerEnumeration
65
+ * @param options
66
+ * @param options.name {string}
67
+ * @param options.enumValues [{key:Name, value:values}]
68
+ * @param options.encode
69
+ * @param options.decode
70
+ * @param options.typedEnum
71
+ * @param options.defaultValue
72
+ * @return {Enum}
73
+ */
74
+ export function registerEnumeration(options: EnumerationDefinitionOptions): Enum {
75
+ assert(Object.prototype.hasOwnProperty.call(options,"name"));
76
+ assert(Object.prototype.hasOwnProperty.call(options,"enumValues"));
77
+ const name = options.name;
78
+
79
+ if (_enumerations.hasOwnProperty(name)) {
80
+ throw new Error("factories.registerEnumeration : Enumeration " + options.name + " has been already inserted");
81
+ }
82
+ const enumerationDefinition = new EnumerationDefinitionSchema(options);
83
+ _enumerations.set(name, enumerationDefinition);
84
+
85
+ return enumerationDefinition.typedEnum;
86
+ }
87
+
88
+ export function hasEnumeration(enumerationName: string): boolean {
89
+ return _enumerations.has(enumerationName);
90
+ }
91
+
92
+ export function getEnumeration(enumerationName: string): EnumerationDefinitionSchema {
93
+ if (!exports.hasEnumeration(enumerationName)) {
94
+ throw new Error("Cannot find enumeration with type " + enumerationName);
95
+ }
96
+ return _enumerations.get(enumerationName) as EnumerationDefinitionSchema;
97
+ }