node-opcua-factory 2.76.2 → 2.77.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.
@@ -24,30 +24,19 @@ const debugLog = make_debugLog(__filename);
24
24
  const doDebug = checkDebugFlag(__filename);
25
25
  const warningLog = make_warningLog(__filename);
26
26
 
27
- export function _findFieldSchema(typeDictionary: DataTypeFactory, field: StructuredTypeField, value: any): IStructuredTypeSchema {
28
- const fieldType = field.fieldType;
29
-
30
- if (field.allowSubType && field.category === "complex") {
31
- const fieldTypeConstructor = value ? value.constructor : field.fieldTypeConstructor;
32
-
33
- const _newFieldSchema = fieldTypeConstructor.schema;
34
-
35
- return _newFieldSchema as IStructuredTypeSchema;
36
- }
37
-
38
- const fieldTypeConstructor = field.fieldTypeConstructor || typeDictionary.getStructureTypeConstructor(fieldType);
39
-
40
- return (field.schema as IStructuredTypeSchema) || (fieldTypeConstructor as any).schema;
27
+ export interface StructureInfo {
28
+ constructor: ConstructorFuncWithSchema | null; // null if abstract
29
+ schema: IStructuredTypeSchema;
41
30
  }
42
-
43
31
  export class DataTypeFactory {
44
32
  public defaultByteOrder: string;
45
33
  public targetNamespace: string;
46
34
  public imports: string[] = [];
47
35
 
48
- private _structureTypeConstructorByNameMap: Map<string, ConstructorFuncWithSchema> = new Map();
49
- private _structureTypeConstructorByDataTypeMap: Map<string, ConstructorFuncWithSchema> = new Map();
50
- private _structureTypeConstructorByEncodingNodeIdMap: Map<string, any> = new Map();
36
+ private _structureInfoByName: Map<string, StructureInfo> = new Map();
37
+ private _structureInfoByDataTypeMap: Map<string, StructureInfo> = new Map();
38
+
39
+ private _structureInfoByEncodingMap: Map<string, StructureInfo> = new Map();
51
40
  private _enumerations: Map<string, EnumerationDefinitionSchema> = new Map();
52
41
 
53
42
  private baseDataFactories: DataTypeFactory[];
@@ -113,23 +102,23 @@ export class DataTypeFactory {
113
102
  }
114
103
  // ----------------------------
115
104
 
116
- public findConstructorForDataType(dataTypeNodeId: NodeId): ConstructorFuncWithSchema {
117
- const constructor = this.getConstructorForDataType(dataTypeNodeId);
118
- if (constructor) {
119
- return constructor;
105
+ public findStructureInfoForDataType(dataTypeNodeId: NodeId): StructureInfo {
106
+ const structureInfo = this.getStructureInfoForDataType(dataTypeNodeId);
107
+ if (structureInfo) {
108
+ return structureInfo;
120
109
  }
121
- this.getConstructorForDataType(dataTypeNodeId);
110
+ this.getStructureInfoForDataType(dataTypeNodeId);
122
111
  throw new Error("Cannot find StructureType constructor for dataType " + dataTypeNodeId.toString());
123
112
  }
124
- public getConstructorForDataType(dataTypeNodeId: NodeId): ConstructorFuncWithSchema | null {
125
- const constructor = this._structureTypeConstructorByDataTypeMap.get(dataTypeNodeId.toString());
126
- if (constructor) {
127
- return constructor;
113
+ public getStructureInfoForDataType(dataTypeNodeId: NodeId): StructureInfo | null {
114
+ const structureInfo = this._structureInfoByDataTypeMap.get(dataTypeNodeId.toString());
115
+ if (structureInfo) {
116
+ return structureInfo;
128
117
  }
129
118
  for (const factory of this.baseDataFactories) {
130
- const constructor2 = factory.getConstructorForDataType(dataTypeNodeId);
131
- if (constructor2) {
132
- return constructor2;
119
+ const structureInfo2 = factory.getStructureInfoForDataType(dataTypeNodeId);
120
+ if (structureInfo2) {
121
+ return structureInfo2;
133
122
  }
134
123
  }
135
124
  return null;
@@ -138,21 +127,24 @@ export class DataTypeFactory {
138
127
  // Access by typeName
139
128
  // ----------------------------------------------------------------------------------------------------
140
129
  public structuredTypesNames(): IterableIterator<string> {
141
- return this._structureTypeConstructorByNameMap.keys();
130
+ return this._structureInfoByName.keys();
131
+ }
132
+ public enumerations(): IterableIterator<string> {
133
+ return this._enumerations.keys();
142
134
  }
143
135
 
144
- public getStructureTypeConstructor(typeName: string): ConstructorFuncWithSchema {
145
- const constructor = this._structureTypeConstructorByNameMap.get(typeName);
146
- if (constructor) {
147
- return constructor;
136
+ public getStructureInfoByTypeName(typeName: string): StructureInfo {
137
+ const structureInfo = this._structureInfoByName.get(typeName);
138
+ if (structureInfo) {
139
+ return structureInfo;
148
140
  }
149
141
  for (const factory of this.baseDataFactories) {
150
- if (!factory.hasStructuredType(typeName)) {
142
+ if (!factory.hasStructureByTypeName(typeName)) {
151
143
  continue;
152
144
  }
153
- const constructor2 = factory.getStructureTypeConstructor(typeName);
154
- if (constructor2) {
155
- return constructor2;
145
+ const structureInfo2 = factory.getStructureInfoByTypeName(typeName);
146
+ if (structureInfo2) {
147
+ return structureInfo2;
156
148
  }
157
149
  }
158
150
  // istanbul ignore next
@@ -165,12 +157,12 @@ export class DataTypeFactory {
165
157
  );
166
158
  }
167
159
 
168
- public hasStructuredType(typeName: string): boolean {
169
- if (this._structureTypeConstructorByNameMap.has(typeName)) {
160
+ public hasStructureByTypeName(typeName: string): boolean {
161
+ if (this._structureInfoByName.has(typeName)) {
170
162
  return true;
171
163
  }
172
164
  for (const factory of this.baseDataFactories) {
173
- if (factory.hasStructuredType(typeName)) {
165
+ if (factory.hasStructureByTypeName(typeName)) {
174
166
  return true;
175
167
  }
176
168
  }
@@ -178,8 +170,8 @@ export class DataTypeFactory {
178
170
  }
179
171
 
180
172
  public getStructuredTypeSchema(typeName: string): IStructuredTypeSchema {
181
- const constructor = this.getStructureTypeConstructor(typeName);
182
- return constructor.schema;
173
+ const structureInfo = this.getStructureInfoByTypeName(typeName);
174
+ return structureInfo.schema;
183
175
  }
184
176
 
185
177
  // istanbul ignore next
@@ -192,8 +184,13 @@ export class DataTypeFactory {
192
184
  console.log(" done");
193
185
  }
194
186
 
187
+ public registerAbstractStructure(dataTypeNodeId: NodeId, className: string, schema: IStructuredTypeSchema) {
188
+ schema.isAbstract = true;
189
+ this._registerFactory(dataTypeNodeId, className, null, schema);
190
+ }
191
+
195
192
  public registerClassDefinition(dataTypeNodeId: NodeId, className: string, classConstructor: ConstructorFuncWithSchema): void {
196
- this._registerFactory(dataTypeNodeId, className, classConstructor);
193
+ this._registerFactory(dataTypeNodeId, className, classConstructor, classConstructor.schema);
197
194
  if (classConstructor.encodingDefaultBinary && classConstructor.encodingDefaultBinary.value !== 0) {
198
195
  this.associateWithBinaryEncoding(className, classConstructor.encodingDefaultBinary);
199
196
  } else {
@@ -207,14 +204,16 @@ export class DataTypeFactory {
207
204
  // ----------------------------------------------------------------------------------------------------
208
205
  public getConstructor(binaryEncodingNodeId: NodeId): ConstructorFunc | null {
209
206
  const expandedNodeIdKey = makeExpandedNodeIdKey(binaryEncodingNodeId);
210
- const constructor = this._structureTypeConstructorByEncodingNodeIdMap.get(expandedNodeIdKey);
211
- if (constructor) {
212
- return constructor;
207
+ const structureInfo = this._structureInfoByEncodingMap.get(expandedNodeIdKey);
208
+ if (!structureInfo) return null;
209
+ const Constructor = structureInfo.constructor;
210
+ if (Constructor) {
211
+ return Constructor;
213
212
  }
214
213
  for (const factory of this.baseDataFactories) {
215
- const constructor2 = factory.getConstructor(binaryEncodingNodeId);
216
- if (constructor2) {
217
- return constructor2;
214
+ const Constructor2 = factory.getConstructor(binaryEncodingNodeId);
215
+ if (Constructor2) {
216
+ return Constructor2;
218
217
  }
219
218
  }
220
219
  debugLog(chalk.red("#getConstructor : cannot find constructor for expandedId "), binaryEncodingNodeId.toString());
@@ -225,13 +224,10 @@ export class DataTypeFactory {
225
224
  if (!binaryEncodingNodeId) {
226
225
  return false;
227
226
  }
228
- /* istanbul ignore next */
229
- if (!verifyExpandedNodeId(binaryEncodingNodeId)) {
230
- console.log("Invalid expandedNodeId");
231
- return false;
232
- }
227
+ verifyExpandedNodeId(binaryEncodingNodeId);
228
+
233
229
  const expandedNodeIdKey = makeExpandedNodeIdKey(binaryEncodingNodeId);
234
- const constructor = this._structureTypeConstructorByEncodingNodeIdMap.get(expandedNodeIdKey);
230
+ const constructor = this._structureInfoByEncodingMap.get(expandedNodeIdKey);
235
231
  if (constructor) {
236
232
  return true;
237
233
  }
@@ -245,43 +241,40 @@ export class DataTypeFactory {
245
241
  }
246
242
 
247
243
  public constructObject(binaryEncodingNodeId: NodeId): IBaseUAObject {
248
- if (!verifyExpandedNodeId(binaryEncodingNodeId)) {
249
- throw new Error(" constructObject : invalid expandedNodeId provided " + binaryEncodingNodeId.toString());
250
- }
251
- const constructor = this.getConstructor(binaryEncodingNodeId);
244
+ verifyExpandedNodeId(binaryEncodingNodeId);
245
+
246
+ const Constructor = this.getConstructor(binaryEncodingNodeId);
252
247
 
253
- if (!constructor) {
248
+ if (!Constructor) {
254
249
  debugLog("Cannot find constructor for " + binaryEncodingNodeId.toString());
255
250
  throw new Error("Cannot find constructor for " + binaryEncodingNodeId.toString());
256
251
  }
257
- return new constructor();
252
+ return new Constructor();
258
253
  }
259
254
 
260
255
  public associateWithBinaryEncoding(className: string, expandedNodeId: ExpandedNodeId): void {
261
- const classConstructor = this.getStructureTypeConstructor(className);
256
+ const structureInfo = this.getStructureInfoByTypeName(className);
262
257
  if (doDebug) {
263
258
  debugLog(" associateWithBinaryEncoding ", className, expandedNodeId.toString());
264
259
  }
265
260
 
266
- /* istanbul ignore next */
267
- if (!verifyExpandedNodeId(expandedNodeId)) {
268
- throw new Error("Invalid expandedNodeId " + expandedNodeId.toString() + " className = " + className);
269
- }
261
+ verifyExpandedNodeId(expandedNodeId);
262
+
270
263
  const expandedNodeIdKey = makeExpandedNodeIdKey(expandedNodeId);
271
264
 
272
265
  /* istanbul ignore next */
273
- if (this._structureTypeConstructorByEncodingNodeIdMap.has(expandedNodeIdKey)) {
266
+ if (this._structureInfoByEncodingMap.has(expandedNodeIdKey)) {
274
267
  throw new Error(
275
268
  " Class " +
276
269
  className +
277
270
  " with ID " +
278
271
  expandedNodeId +
279
272
  " already in constructorMap for " +
280
- this._structureTypeConstructorByEncodingNodeIdMap.get(expandedNodeIdKey).name
273
+ this._structureInfoByEncodingMap.get(expandedNodeIdKey)!.schema.name
281
274
  );
282
275
  }
283
276
 
284
- this._structureTypeConstructorByEncodingNodeIdMap.set(expandedNodeIdKey, classConstructor);
277
+ this._structureInfoByEncodingMap.set(expandedNodeIdKey, structureInfo);
285
278
  }
286
279
 
287
280
  public toString(): string {
@@ -293,25 +286,34 @@ export class DataTypeFactory {
293
286
  return l.join("\n");
294
287
  }
295
288
 
296
- private _registerFactory(dataTypeNodeId: NodeId, typeName: string, constructor: ConstructorFuncWithSchema): void {
297
-
289
+ private _registerFactory(
290
+ dataTypeNodeId: NodeId,
291
+ typeName: string,
292
+ constructor: ConstructorFuncWithSchema | null,
293
+ schema: IStructuredTypeSchema
294
+ ): void {
298
295
  /* istanbul ignore next */
299
- if (this._structureTypeConstructorByNameMap.has(typeName)) {
300
- warningLog(this.getStructureTypeConstructor(typeName));
296
+ if (this._structureInfoByName.has(typeName)) {
297
+ warningLog(this.getStructureInfoByTypeName(typeName));
301
298
  warningLog("target namespace = `" + this.targetNamespace + "`");
302
299
  warningLog(" registerFactory : " + typeName + " already registered. dataTypeNodeId=", dataTypeNodeId.toString());
303
300
  return;
304
301
  }
305
- debugLog("registering typeName ", typeName, dataTypeNodeId.toString());
306
- this._structureTypeConstructorByNameMap.set(typeName, constructor);
302
+ debugLog("registering typeName ", typeName, dataTypeNodeId.toString(), "isAbstract ", schema.isAbstract);
303
+ const structureInfo = { constructor, schema };
304
+ this._structureInfoByName.set(typeName, structureInfo);
307
305
  if (dataTypeNodeId.value !== 0) {
308
- this._structureTypeConstructorByDataTypeMap.set(dataTypeNodeId.toString(), constructor);
306
+ this._structureInfoByDataTypeMap.set(dataTypeNodeId.toString(), structureInfo);
309
307
  }
310
- Object.defineProperty(constructor.schema, "$$factory", {
311
- enumerable: false,
312
- value: this,
313
- writable: false
314
- });
308
+
309
+ // console.log("is this neceesary anymore ?");
310
+ // if (constructor) {
311
+ // Object.defineProperty(constructor.schema, "$$factory", {
312
+ // enumerable: false,
313
+ // value: this,
314
+ // writable: false
315
+ // });
316
+ // }
315
317
  }
316
318
  }
317
319
 
@@ -329,7 +331,7 @@ function dumpDataFactory(dataFactory: DataTypeFactory, write: any) {
329
331
 
330
332
  write("structureTypeName =", structureTypeName);
331
333
 
332
- if (!dataFactory.getConstructorForDataType(schema.dataTypeNodeId)) {
334
+ if (!dataFactory.getStructureInfoForDataType(schema.dataTypeNodeId)) {
333
335
  write(" ( No constructor for " + schema.name + " " + schema.dataTypeNodeId.toString());
334
336
  }
335
337
  if (!schema.encodingDefaultBinary) {
@@ -18,20 +18,16 @@ export function getStandardDataTypeFactory(): DataTypeFactory {
18
18
  }
19
19
 
20
20
  export function getStructureTypeConstructor(typeName: string): ConstructorFuncWithSchema {
21
- return getStandardDataTypeFactory().getStructureTypeConstructor(typeName);
22
- }
23
-
24
- export function hasStructuredType(typeName: string): boolean {
25
- return getStandardDataTypeFactory().hasStructuredType(typeName);
26
- }
27
-
28
- export function getConstructor(binaryEncodingNodeId: ExpandedNodeId): ConstructorFunc | null {
29
- return getStandardDataTypeFactory().getConstructor(binaryEncodingNodeId);
21
+ const structureInfo = getStandardDataTypeFactory().getStructureInfoByTypeName(typeName);
22
+ if (!structureInfo) {
23
+ throw new Error("cannot find Structure Information for "+ typeName)
24
+ }
25
+ if (!structureInfo.constructor) {
26
+ throw new Error("cannot Structure is Abstract ! "+ typeName)
27
+ }
28
+ return structureInfo.constructor;
30
29
  }
31
30
 
32
- export function hasConstructor(binaryEncodingNodeId: ExpandedNodeId): boolean {
33
- return getStandardDataTypeFactory().hasConstructor(binaryEncodingNodeId);
34
- }
35
31
 
36
32
 
37
33
  /* istanbul ignore next */
@@ -2,9 +2,9 @@ import { ExpandedNodeId } from "node-opcua-nodeid";
2
2
  import { getStandardDataTypeFactory } from "./get_standard_data_type_factory";
3
3
  import { IBaseUAObject, IStructuredTypeSchema } from "./types";
4
4
 
5
- export function getStructuredTypeSchema(typeName: string): IStructuredTypeSchema {
6
- return getStandardDataTypeFactory().getStructuredTypeSchema(typeName);
7
- }
8
- export function constructObject(binaryEncodingNodeId: ExpandedNodeId): IBaseUAObject {
9
- return getStandardDataTypeFactory().constructObject(binaryEncodingNodeId);
10
- }
5
+ // export function getStructuredTypeSchema(typeName: string): IStructuredTypeSchema {
6
+ // return getStandardDataTypeFactory().getStructuredTypeSchema(typeName);
7
+ // }
8
+ // export function constructObject(binaryEncodingNodeId: ExpandedNodeId): IBaseUAObject {
9
+ // return getStandardDataTypeFactory().constructObject(binaryEncodingNodeId);
10
+ // }
@@ -46,7 +46,7 @@ export function initialize_field(field: StructuredTypeField, value: unknown, fac
46
46
  }
47
47
  if (field.category === FieldCategory.complex) {
48
48
  if (field.fieldTypeConstructor) {
49
- return new field.fieldTypeConstructor(value);
49
+ return new field.fieldTypeConstructor(value as Record<string,unknown>);
50
50
  } else {
51
51
  debugLog("xxxx => missing constructor for field type", field.fieldType);
52
52
  }
@@ -5,15 +5,14 @@ import * as chalk from "chalk";
5
5
 
6
6
  import { assert } from "node-opcua-assert";
7
7
  import { BinaryStream } from "node-opcua-binary-stream";
8
+ import { make_warningLog } from "node-opcua-debug";
8
9
  import { ExpandedNodeId, NodeId } from "node-opcua-nodeid";
9
10
  import { lowerFirstLetter } from "node-opcua-utils";
10
-
11
- import { getBuiltInType, hasBuiltInType, TypeSchemaBase } from "./builtin_types";
12
- import { getBuiltInEnumeration, hasBuiltInEnumeration } from "./enumerations";
11
+ import { TypeSchemaBase } from "./builtin_types";
13
12
  import { parameters } from "./parameters";
14
- import { getStructureTypeConstructor, hasStructuredType } from "./get_standard_data_type_factory";
15
- import { getStructuredTypeSchema } from "./get_structured_type_schema";
13
+ import { getStandardDataTypeFactory } from "./get_standard_data_type_factory";
16
14
  import {
15
+ BitField,
17
16
  CommonInterface,
18
17
  FieldCategory,
19
18
  FieldInterfaceOptions,
@@ -21,29 +20,33 @@ import {
21
20
  IStructuredTypeSchema,
22
21
  StructuredTypeOptions
23
22
  } from "./types";
23
+ import { DataTypeFactory } from "./datatype_factory";
24
+
25
+ const warningLog = make_warningLog(__filename);
24
26
 
25
- function figureOutFieldCategory(field: FieldInterfaceOptions): FieldCategory {
27
+ function figureOutFieldCategory(field: FieldInterfaceOptions, dataTypeFactory: DataTypeFactory): FieldCategory {
26
28
  const fieldType = field.fieldType;
27
29
 
28
30
  if (field.category) {
29
31
  return field.category;
30
32
  }
31
-
32
- if (hasBuiltInEnumeration(fieldType)) {
33
+ if (dataTypeFactory.hasEnumeration(fieldType)) {
33
34
  return FieldCategory.enumeration;
34
- } else if (hasBuiltInType(fieldType)) {
35
+ } else if (dataTypeFactory.hasBuiltInType(fieldType)) {
35
36
  return FieldCategory.basic;
36
- } else if (hasStructuredType(fieldType)) {
37
+ } else if (dataTypeFactory.hasStructureByTypeName(fieldType)) {
37
38
  assert(fieldType !== "LocalizedText"); // LocalizedText should be treated as BasicType!!!
38
39
  return FieldCategory.complex;
39
40
  }
41
+ warningLog("Cannot figure out field category for ", field);
40
42
  return FieldCategory.basic;
41
43
  }
42
44
 
43
45
  const regExp = /((ns[0-9]+:)?)(.*)/;
44
46
 
45
47
  function figureOutSchema(
46
- underConstructSchema: StructuredTypeSchema,
48
+ underConstructSchema: IStructuredTypeSchema,
49
+ dataTypeFactory: DataTypeFactory,
47
50
  field: FieldInterfaceOptions,
48
51
  category: FieldCategory
49
52
  ): CommonInterface {
@@ -67,29 +70,32 @@ function figureOutSchema(
67
70
 
68
71
  switch (category) {
69
72
  case FieldCategory.complex:
70
- if (hasStructuredType(field.fieldType)) {
71
- returnValue = getStructuredTypeSchema(fieldTypeWithoutNS);
73
+ if (dataTypeFactory.hasStructureByTypeName(field.fieldType)) {
74
+ returnValue = dataTypeFactory.getStructuredTypeSchema(fieldTypeWithoutNS);
72
75
  } else {
73
76
  // LocalizedText etc ...
74
- returnValue = getBuiltInType(fieldTypeWithoutNS);
77
+ returnValue = dataTypeFactory.getBuiltInType(fieldTypeWithoutNS);
75
78
  }
76
79
  break;
77
80
  case FieldCategory.basic:
78
- returnValue = getBuiltInType(fieldTypeWithoutNS);
81
+ returnValue = dataTypeFactory.getBuiltInType(fieldTypeWithoutNS);
79
82
  if (!returnValue) {
80
- returnValue = getStructuredTypeSchema(fieldTypeWithoutNS);
83
+ if (dataTypeFactory.hasEnumeration(fieldTypeWithoutNS)) {
84
+ warningLog("expecing a enumeration!");
85
+ }
86
+ returnValue = dataTypeFactory.getStructuredTypeSchema(fieldTypeWithoutNS);
81
87
  if (returnValue) {
82
88
  console.log("Why ?");
83
89
  }
84
90
  }
85
91
  break;
86
92
  case FieldCategory.enumeration:
87
- returnValue = getBuiltInEnumeration(fieldTypeWithoutNS);
93
+ returnValue = dataTypeFactory.getEnumeration(fieldTypeWithoutNS);
88
94
  break;
89
95
  }
90
96
  if (null === returnValue || undefined === returnValue) {
91
97
  try {
92
- returnValue = getBuiltInEnumeration(fieldTypeWithoutNS);
98
+ returnValue = dataTypeFactory.getEnumeration(fieldTypeWithoutNS);
93
99
  } catch (err) {
94
100
  console.log(err);
95
101
  }
@@ -108,9 +114,14 @@ function figureOutSchema(
108
114
  return returnValue;
109
115
  }
110
116
 
111
- function buildField(underConstructSchema: StructuredTypeSchema, fieldLight: FieldInterfaceOptions): FieldType {
112
- const category = figureOutFieldCategory(fieldLight);
113
- const schema = figureOutSchema(underConstructSchema, fieldLight, category);
117
+ function buildField(
118
+ underConstructSchema: IStructuredTypeSchema,
119
+ dataTypeFactory: DataTypeFactory,
120
+ fieldLight: FieldInterfaceOptions,
121
+ _index: number
122
+ ): FieldType {
123
+ const category = figureOutFieldCategory(fieldLight, dataTypeFactory);
124
+ const schema = figureOutSchema(underConstructSchema, dataTypeFactory, fieldLight, category);
114
125
 
115
126
  /* istanbul ignore next */
116
127
  if (!schema) {
@@ -120,7 +131,9 @@ function buildField(underConstructSchema: StructuredTypeSchema, fieldLight: Fiel
120
131
  " with type " +
121
132
  fieldLight.fieldType +
122
133
  " category" +
123
- category
134
+ category +
135
+ " at index" +
136
+ _index
124
137
  );
125
138
  }
126
139
 
@@ -142,14 +155,13 @@ function buildField(underConstructSchema: StructuredTypeSchema, fieldLight: Fiel
142
155
  schema
143
156
  };
144
157
  }
158
+
145
159
  export class StructuredTypeSchema extends TypeSchemaBase implements IStructuredTypeSchema {
146
160
  public fields: FieldType[];
147
- public id: NodeId;
148
161
  public dataTypeNodeId: NodeId;
149
162
 
150
163
  public baseType: string;
151
- public _possibleFields: string[];
152
- public _baseSchema: IStructuredTypeSchema | null;
164
+ private _baseSchema: IStructuredTypeSchema | null | undefined;
153
165
 
154
166
  public documentation?: string;
155
167
 
@@ -162,7 +174,9 @@ export class StructuredTypeSchema extends TypeSchemaBase implements IStructuredT
162
174
  public encodingDefaultXml?: ExpandedNodeId;
163
175
  public encodingDefaultJson?: ExpandedNodeId;
164
176
 
165
- public bitFields?: any[];
177
+ public bitFields?: BitField[];
178
+
179
+ private _dataTypeFactory: DataTypeFactory;
166
180
 
167
181
  constructor(options: StructuredTypeOptions) {
168
182
  super(options);
@@ -172,21 +186,36 @@ export class StructuredTypeSchema extends TypeSchemaBase implements IStructuredT
172
186
  this.baseType = options.baseType;
173
187
  this.category = FieldCategory.complex;
174
188
 
175
- if (hasBuiltInType(options.name)) {
189
+ this._dataTypeFactory = options.dataTypeFactory;
190
+ if (this._dataTypeFactory.hasBuiltInType(options.name)) {
176
191
  this.category = FieldCategory.basic;
177
192
  }
178
- this.fields = options.fields.map(buildField.bind(null, this));
179
- this.id = new NodeId();
180
193
  this.dataTypeNodeId = new NodeId();
194
+ this._baseSchema = undefined;
195
+ this.fields = options.fields.map(buildField.bind(null, this, this._dataTypeFactory));
196
+ }
197
+
198
+ getDataTypeFactory(): DataTypeFactory {
199
+ return this._dataTypeFactory || getStandardDataTypeFactory();
200
+ }
181
201
 
182
- this._possibleFields = this.fields.map((field) => field.name);
183
- this._baseSchema = null;
202
+ getBaseSchema(): IStructuredTypeSchema | null {
203
+ if (this._baseSchema !== undefined && this._baseSchema === null && this.baseType === "ExtensionObject") {
204
+ return this._baseSchema;
205
+ }
206
+ const _schemaBase = _get_base_schema(this);
207
+ this._baseSchema = _schemaBase;
208
+ return _schemaBase || null;
184
209
  }
210
+
211
+ public getPossibleFieldsLocal() {
212
+ return this.fields.map((field) => field.name);
213
+ }
214
+
185
215
  public toString(): string {
186
216
  const str: string[] = [];
187
217
  str.push("name = " + this.name);
188
218
  str.push("baseType = " + this.baseType);
189
- str.push("id = " + this.id.toString());
190
219
  str.push("bitFields = " + (this.bitFields ? this.bitFields.map((b) => b.name).join(" ") : undefined));
191
220
  str.push("dataTypeNodeId = " + (this.dataTypeNodeId ? this.dataTypeNodeId.toString() : undefined));
192
221
  str.push("documentation = " + this.documentation);
@@ -209,18 +238,8 @@ export class StructuredTypeSchema extends TypeSchemaBase implements IStructuredT
209
238
  }
210
239
  }
211
240
 
212
- /**
213
- *
214
- * @method get_base_schema
215
- * @param schema
216
- * @return {*}
217
- *
218
- */
219
- export function get_base_schema(schema: IStructuredTypeSchema): IStructuredTypeSchema | null {
220
- let baseSchema = schema._baseSchema;
221
- if (baseSchema) {
222
- return baseSchema;
223
- }
241
+ function _get_base_schema(schema: IStructuredTypeSchema): IStructuredTypeSchema | null | undefined {
242
+ const dataTypeFactory = schema.getDataTypeFactory();
224
243
 
225
244
  if (schema.baseType === "ExtensionObject" || schema.baseType === "DataTypeDefinition") {
226
245
  return null;
@@ -229,23 +248,28 @@ export function get_base_schema(schema: IStructuredTypeSchema): IStructuredTypeS
229
248
  return null;
230
249
  }
231
250
 
232
- if (schema.baseType && schema.baseType !== "BaseUAObject" && schema.baseType !== "DataTypeDefinition") {
233
- if (!hasStructuredType(schema.baseType)) {
234
- return null;
251
+ if (
252
+ schema.baseType &&
253
+ schema.baseType !== "BaseUAObject" &&
254
+ schema.baseType !== "Structure" &&
255
+ schema.baseType !== "DataTypeDefinition"
256
+ ) {
257
+ if (!dataTypeFactory.hasStructureByTypeName(schema.baseType)) {
258
+ warningLog(`Cannot find schema for ${schema.baseType} in dataTypeFactory for ${schema.name}: fix me !`);
259
+ return undefined;
235
260
  }
236
- const baseType = getStructureTypeConstructor(schema.baseType);
261
+ const structureInfo = dataTypeFactory.getStructureInfoByTypeName(schema.baseType);
237
262
 
238
263
  // istanbul ignore next
239
- if (!baseType) {
264
+ if (!structureInfo) {
240
265
  throw new Error(" cannot find factory for " + schema.baseType);
241
266
  }
242
- if (baseType.prototype.schema) {
243
- baseSchema = baseType.prototype.schema;
267
+ if (structureInfo.schema) {
268
+ return structureInfo.schema;
244
269
  }
245
270
  }
246
271
  // put in cache for speedup
247
- schema._baseSchema = baseSchema;
248
- return baseSchema;
272
+ return null;
249
273
  }
250
274
 
251
275
  /**
@@ -253,25 +277,18 @@ export function get_base_schema(schema: IStructuredTypeSchema): IStructuredTypeS
253
277
  * (by walking up the inheritance chain)
254
278
  *
255
279
  */
256
- export function extract_all_fields(schema: IStructuredTypeSchema): string[] {
280
+ export function extractAllPossibleFields(schema: IStructuredTypeSchema): string[] {
257
281
  // returns cached result if any
258
282
  // istanbul ignore next
259
- if (schema._possibleFields) {
260
- return schema._possibleFields;
261
- }
262
283
  // extract the possible fields from the schema.
263
284
  let possibleFields = schema.fields.map((field) => field.name);
264
285
 
265
- const baseSchema = get_base_schema(schema);
266
-
286
+ const baseSchema = schema.getBaseSchema();
267
287
  // istanbul ignore next
268
288
  if (baseSchema) {
269
- const fields = extract_all_fields(baseSchema);
289
+ const fields = extractAllPossibleFields(baseSchema);
270
290
  possibleFields = fields.concat(possibleFields);
271
291
  }
272
-
273
- // put in cache to speed up
274
- schema._possibleFields = possibleFields;
275
292
  return possibleFields;
276
293
  }
277
294
 
@@ -304,7 +321,7 @@ export function check_options_correctness_against_schema(obj: any, schema: IStru
304
321
  }
305
322
 
306
323
  // extract the possible fields from the schema.
307
- const possibleFields: string[] = obj.constructor.possibleFields || schema._possibleFields;
324
+ const possibleFields: string[] = obj.constructor.possibleFields || extractAllPossibleFields(schema);
308
325
 
309
326
  // extracts the fields exposed by the option object
310
327
  const currentFields = Object.keys(options);
@@ -335,6 +352,9 @@ export function check_options_correctness_against_schema(obj: any, schema: IStru
335
352
  return true;
336
353
  }
337
354
 
338
- export function buildStructuredType(schemaLight: StructuredTypeOptions): StructuredTypeSchema {
339
- return new StructuredTypeSchema(schemaLight);
355
+ export function buildStructuredType(schemaLight: Omit<StructuredTypeOptions, "dataTypeFactory">): IStructuredTypeSchema {
356
+ return new StructuredTypeSchema({
357
+ ...schemaLight,
358
+ dataTypeFactory: getStandardDataTypeFactory()
359
+ });
340
360
  }