node-opcua-modeler 2.62.7 → 2.64.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.
@@ -1,10 +1,24 @@
1
1
  /* eslint-disable max-statements */
2
- import { BaseNode, Namespace, UADataType, UAObjectType, UAReferenceType, UAVariableType } from "node-opcua-address-space";
2
+ import {
3
+ BaseNode,
4
+ dumpReferenceDescription,
5
+ Namespace,
6
+ UADataType,
7
+ UAObject,
8
+ UAObjectType,
9
+ UAReferenceType,
10
+ UAVariable,
11
+ UAVariableType
12
+ } from "node-opcua-address-space";
3
13
  import { coerceUInt32 } from "node-opcua-basic-types";
4
- import { DataTypeDefinition, EnumDefinition, StructureDefinition, StructureField } from "node-opcua-types";
14
+ import { NodeClass } from "node-opcua-data-model";
15
+ import { NodeId } from "node-opcua-nodeid";
16
+ import { StructureField } from "node-opcua-types";
5
17
  import { DataType } from "node-opcua-variant";
18
+
6
19
  import { displayNodeElement } from "./displayNodeElement";
7
20
  import { TableHelper } from "./tableHelper";
21
+ import { dumpClassHierachry, graphVizToPlantUml, opcuaToDot } from "./to_graphivz";
8
22
 
9
23
  interface NamespacePriv2 {
10
24
  nodeIterator(): IterableIterator<BaseNode>;
@@ -40,48 +54,167 @@ export async function buildDocumentationToString(namespace: Namespace): Promise<
40
54
  return writer.toString();
41
55
  }
42
56
 
43
- function dataTypeToMarkdown(dataType: UADataType): string {
57
+ interface V {
58
+ valueRank?: number;
59
+ arrayDimensions?: number[];
60
+ dataType: NodeId;
61
+ }
62
+ const toDataTypeStr = (p: BaseNode): string => {
63
+ if (p.nodeClass === NodeClass.Variable) {
64
+ const v = p as UAVariable;
65
+ const arr = v.valueRank == 1 ? "[]" : "";
66
+ const brn = toDataTypeStr((p as UAVariable).dataTypeObj);
67
+ return brn + arr;
68
+ }
69
+ if (p.nodeClass === NodeClass.DataType) {
70
+ const dataType = p as UADataType;
71
+ const brn = dataType.browseName.toString();
72
+ return brn;
73
+ }
74
+ return "";
75
+ };
76
+ function dataTypeEnumerationToMarkdown(dataType: UADataType): string {
44
77
  const addressSpace = dataType.addressSpace;
78
+ const writer = new Writer();
79
+
80
+ writer.writeLine("");
81
+ if (dataType.description) {
82
+ writer.writeLine(dataType.description.text || "");
83
+ }
84
+
85
+ writer.writeLine(`\nThe fields of the ${dataType.browseName.name} DataType are defined in the following table:`);
86
+
87
+ writer.writeLine("");
88
+ const definition = dataType.getEnumDefinition();
89
+ writer.writeLine("\nBasic Type: " + (DataType as any)[DataType.Int32]);
90
+ writer.writeLine("");
91
+
92
+ const table = new TableHelper(["Name", "Value", "Description"]);
93
+ for (const f of definition.fields || []) {
94
+ table.push([f.name, coerceUInt32(f.value[1]), f.description.text || ""]);
95
+ }
96
+ writer.writeLine(table.toMarkdownTable());
97
+
98
+ const str = dumpTypeRepresentation(dataType);
99
+ writer.writeLine(str);
100
+
101
+ return writer.toString();
102
+ }
45
103
 
104
+ function dumpTypeRepresentation(uaType: UAObjectType | UADataType | UAReferenceType): string {
105
+ const className = NodeClass[uaType.nodeClass];
46
106
  const writer = new Writer();
47
- const definition: DataTypeDefinition = dataType.getDefinition();
107
+ writer.writeLine("\n");
108
+ writer.writeLine(
109
+ `\nThe representation of the ${uaType.browseName.name} ${className} in the address space is shown in the following table:`
110
+ );
48
111
 
49
- writer.writeLine("\nisAbstract: " + (dataType.isAbstract ? "Yes" : "No"));
50
- if (dataType.subtypeOfObj) {
51
- writer.writeLine("\nSubtype of " + dataType.subtypeOfObj?.browseName.toString());
112
+ const table = new TableHelper(["Name", "Attribute"]);
113
+ table.push(["NodeId", uaType.nodeId.toString()]);
114
+ table.push(["NamespaceUri", uaType.addressSpace.getNamespaceUri(uaType.nodeId.namespace)]);
115
+ table.push(["BrowseName", uaType.browseName.name!.toString()]);
116
+ table.push(["NodeClass", NodeClass[uaType.nodeClass]]);
117
+ if (uaType.nodeClass === NodeClass.ReferenceType) {
118
+ table.push(["InverseName", (uaType as UAReferenceType).inverseName!.text]);
119
+ // table.push(["IsSymmetric", (uaType as UAReferenceType).isSymetric ? "Yes" : "No"]);
52
120
  }
121
+ table.push(["IsAbstract", uaType.isAbstract ? "Yes" : "No"]);
122
+ table.push(["SubtypeOf", uaType.subtypeOfObj ? uaType.subtypeOfObj.browseName.toString() : ""]);
123
+ writer.writeLine("");
124
+ writer.writeLine(table.toMarkdownTable());
53
125
  writer.writeLine("");
54
126
 
55
- if (definition instanceof EnumDefinition) {
56
- writer.writeLine("\nBasic Type: " + (DataType as any)[DataType.UInt32]);
57
- writer.writeLine("");
127
+ // forward refereces
128
+ {
129
+ const properties = uaType.findReferencesExAsObject("HasProperty");
130
+ const table = new TableHelper(["Reference", "NodeClass", "BrowseName", "DataType", "TypeDefinition", "ModellingRule"]);
58
131
 
59
- const table = new TableHelper(["Name", "Value", "Description"]);
60
- for (const f of definition.fields || []) {
61
- table.push([f.name, coerceUInt32(f.value[1]), f.description.text || ""]);
132
+ if (uaType.subtypeOfObj) {
133
+ const referenceName = "HasSubType";
134
+ const p = uaType.subtypeOfObj!;
135
+ const nodeClass = NodeClass[p.nodeClass];
136
+ const browseName = p.browseName.toString();
137
+ const dataTypeStr = toDataTypeStr(p);
138
+ const modellingRule = p.modellingRule || "";
139
+ const typeDefinitionName = "";
140
+ table.push([referenceName, nodeClass, browseName, dataTypeStr, typeDefinitionName, modellingRule]);
62
141
  }
142
+ if (properties.length > 0) {
143
+ writer.writeLine(`\nThe reference of the ${uaType.browseName.name} ${className} is shown in the following table:`);
144
+ writer.writeLine("");
145
+ for (const p of properties) {
146
+ const referenceName = "HasProperty";
147
+ const nodeClass = NodeClass[p.nodeClass];
148
+ const browseName = p.browseName.toString();
149
+ const dataTypeStr = toDataTypeStr(p);
150
+ const typeDefinitionName = (p as UAVariable | UAObject).typeDefinitionObj?.browseName.toString();
151
+ const modellingRule = p.modellingRule || "";
152
+ table.push([referenceName, nodeClass, browseName, dataTypeStr, typeDefinitionName, modellingRule]);
153
+ }
154
+ }
155
+ writer.writeLine("");
63
156
  writer.writeLine(table.toMarkdownTable());
64
- } else if (definition instanceof StructureDefinition) {
65
- writer.writeLine("\nBasic Type: " + (DataType as any)[dataType.basicDataType]);
157
+ writer.writeLine("");
158
+ }
159
+ return writer.toString();
160
+ }
161
+ function dataTypeStructureToMarkdown(dataType: UADataType): string {
162
+ const addressSpace = dataType.addressSpace;
163
+ const writer = new Writer();
164
+
165
+ writer.writeLine("");
166
+ if (dataType.description) {
167
+ writer.writeLine(dataType.description.text || "");
168
+ }
66
169
 
67
- const table = new TableHelper(["Name", "data type", "value rank", "maxStringLength", "Dimensions", "Description"]);
68
-
69
- for (const f of definition.fields || []) {
70
- const dataTypeString = addressSpace.findDataType(f.dataType)!.browseName.toString();
71
- table.push([
72
- f.name,
73
- dataTypeString,
74
- f.valueRank ? f.valueRank : "",
75
- f.maxStringLength ? f.maxStringLength : "",
76
- f.arrayDimensions ? f.arrayDimensions : "",
77
- f.description.text || ""
78
- ]);
170
+ const definition = dataType.getStructureDefinition();
171
+ writer.writeLine("\nBasic Type: " + (DataType as any)[dataType.basicDataType]);
172
+ writer.writeLine("");
173
+ writer.writeLine(`The fields of the ${dataType.browseName.name} DataType are defined in the following table:`);
174
+
175
+ const c = (f: StructureField) => {
176
+ let dataTypeString = addressSpace.findDataType(f.dataType)!.browseName.toString();
177
+ if (f.valueRank === 1) {
178
+ dataTypeString += "[]";
179
+ } else if (f.valueRank >= 2) {
180
+ dataTypeString += "[" + f.arrayDimensions?.map((d) => "" + d).join(" ") + "]";
79
181
  }
80
- writer.writeLine(table.toMarkdownTable());
182
+ // f.maxStringLength ? f.maxStringLength : "",
183
+ // f.arrayDimensions ? f.arrayDimensions : "",
184
+ return dataTypeString;
185
+ };
186
+ const table = new TableHelper(["Name", "Type", "Description"]);
187
+ table.push([dataType.browseName.name, "Structure"]);
188
+ for (const f of definition.fields || []) {
189
+ table.push([" " + f.name, c(f), (f.description.text || "").replace(/\n/g, "<br>")]);
190
+ }
191
+ writer.writeLine(table.toMarkdownTable());
192
+
193
+ const str = dumpTypeRepresentation(dataType);
194
+ writer.writeLine(str);
195
+
196
+ return writer.toString();
197
+ }
198
+ function dataTypeToMarkdown(dataType: UADataType): string {
199
+ if (dataType.isEnumeration()) {
200
+ return dataTypeEnumerationToMarkdown(dataType);
201
+ } else if (dataType.isStructure()) {
202
+ return dataTypeStructureToMarkdown(dataType);
81
203
  } else {
204
+ const writer = new Writer();
205
+ writer.writeLine("");
206
+ if (dataType.description) {
207
+ writer.writeLine(dataType.description.text || "");
208
+ }
82
209
  writer.writeLine("\nBasic Type: " + (DataType as any)[dataType.basicDataType]);
83
210
  writer.writeLine("");
211
+ return writer.toString();
84
212
  }
213
+ }
214
+ function dumpReferenceType(referenceType: UAReferenceType): string {
215
+ const writer = new Writer();
216
+ const str = dumpTypeRepresentation(referenceType);
217
+ writer.writeLine(str);
85
218
  return writer.toString();
86
219
  }
87
220
  export async function buildDocumentation(namespace: Namespace, writer: IWriter): Promise<void> {
@@ -95,63 +228,82 @@ export async function buildDocumentation(namespace: Namespace, writer: IWriter):
95
228
  writer.writeLine("");
96
229
  writer.writeLine("# Namespace " + namespaceUri);
97
230
  writer.writeLine("");
231
+
232
+ const namespacePriv = namespace as unknown as NamespacePriv2;
98
233
  // -------------- writeReferences
99
- const namespacePriv = (namespace as unknown) as NamespacePriv2;
100
- writer.writeLine("");
101
- writer.writeLine("## References ");
102
- writer.writeLine("");
103
- for (const referenceType of namespacePriv._referenceTypeIterator()) {
104
- writer.writeLine("\n\n### reference " + referenceType.browseName.name!);
234
+ if (namespacePriv._referenceTypeCount() > 0) {
235
+ writer.writeLine("");
236
+ writer.writeLine("## References ");
237
+ writer.writeLine("");
238
+ for (const referenceType of namespacePriv._referenceTypeIterator()) {
239
+ writer.writeLine("\n\n### reference " + referenceType.browseName.name!);
240
+ dumpReferenceType(referenceType);
241
+ }
105
242
  }
106
-
107
243
  function d(node: BaseNode): string {
108
244
  return node.description ? node.description!.text!.toString() : "";
109
245
  }
110
246
  // -------------- writeDataType
111
- writer.writeLine("");
112
- writer.writeLine("## DataTypes");
113
- writer.writeLine("");
114
- for (const dataType of namespacePriv._dataTypeIterator()) {
115
- writer.writeLine("\n\n### " + dataType.browseName.name!.toString());
247
+ if (namespacePriv._dataTypeCount() > 0) {
116
248
  writer.writeLine("");
117
- writer.writeLine(dataTypeToMarkdown(dataType));
118
- }
119
- // -------------- writeObjectType
120
- writer.writeLine("");
121
- writer.writeLine("## ObjectTypes");
122
- writer.writeLine("");
123
- for (const objectType of namespacePriv._objectTypeIterator()) {
124
- writer.writeLine("\n\n### " + objectType.browseName.name!.toString());
125
- writer.writeLine(d(objectType));
126
- // enumerate components
127
- writer.writeLine(displayNodeElement(objectType, { format: "markdown" }));
128
-
129
- for (const comp of objectType.getComponents()) {
130
- writer.writeLine("\n\n#### " + comp.browseName.name!.toString());
249
+ writer.writeLine("## DataTypes");
250
+ writer.writeLine("");
251
+ for (const dataType of namespacePriv._dataTypeIterator()) {
252
+ writer.writeLine("\n\n### " + dataType.browseName.name!.toString());
131
253
  writer.writeLine("");
132
- writer.writeLine(d(comp));
254
+ writer.writeLine(dataTypeToMarkdown(dataType));
133
255
  }
134
- for (const comp of objectType.getProperties()) {
135
- writer.writeLine("\n\n#### " + comp.browseName.name!.toString());
136
- writer.writeLine("");
137
- writer.writeLine(d(comp));
256
+ }
257
+ // -------------- writeObjectType
258
+ if (namespacePriv._objectTypeCount() > 0) {
259
+ writer.writeLine("");
260
+ writer.writeLine("## ObjectTypes");
261
+ writer.writeLine("");
262
+ for (const objectType of namespacePriv._objectTypeIterator()) {
263
+ writer.writeLine("\n\n### " + objectType.browseName.name!.toString());
264
+ writer.writeLine(d(objectType));
265
+
266
+ writer.writeLine(graphVizToPlantUml(dumpClassHierachry(objectType, { showBaseType: true, depth: 2 })));
267
+
268
+ writer.writeLine(graphVizToPlantUml(opcuaToDot(objectType)));
269
+
270
+ // enumerate components
271
+ writer.writeLine(displayNodeElement(objectType, { format: "markdown" }));
272
+
273
+ for (const comp of objectType.getComponents()) {
274
+ writer.writeLine("\n\n#### " + comp.browseName.name!.toString());
275
+ writer.writeLine("");
276
+ writer.writeLine(d(comp));
277
+ }
278
+ for (const comp of objectType.getProperties()) {
279
+ writer.writeLine("\n\n#### " + comp.browseName.name!.toString());
280
+ writer.writeLine("");
281
+ writer.writeLine(d(comp));
282
+ }
138
283
  }
139
284
  }
140
285
  // -------------- writeVariableType
141
- writer.writeLine("");
142
- writer.writeLine("## VariableTypes");
143
- writer.writeLine("");
144
- for (const variableType of namespacePriv._variableTypeIterator()) {
145
- writer.writeLine("\n\n### " + variableType.browseName.name!.toString());
146
- writer.writeLine(d(variableType));
286
+ if (namespacePriv._variableTypeCount() > 0) {
147
287
  writer.writeLine("");
148
- // enumerate components
149
- writer.writeLine(displayNodeElement(variableType, { format: "markdown" }));
150
- for (const reference of variableType.allReferences()) {
151
- const n = reference.node!;
152
- writer.writeLine("\n\n#### " + n.browseName.name!.toString());
288
+ writer.writeLine("## VariableTypes");
289
+ writer.writeLine("");
290
+ for (const variableType of namespacePriv._variableTypeIterator()) {
291
+ writer.writeLine("\n\n### " + variableType.browseName.name!.toString());
292
+ writer.writeLine(d(variableType));
153
293
  writer.writeLine("");
154
- writer.writeLine(d(n));
294
+
295
+ writer.writeLine(graphVizToPlantUml(dumpClassHierachry(variableType, { showBaseType: true, depth: 2 })));
296
+
297
+ writer.writeLine(graphVizToPlantUml(opcuaToDot(variableType)));
298
+
299
+ // enumerate components
300
+ writer.writeLine(displayNodeElement(variableType, { format: "markdown" }));
301
+ for (const reference of variableType.allReferences()) {
302
+ const n = reference.node!;
303
+ writer.writeLine("\n\n#### " + n.browseName.name!.toString());
304
+ writer.writeLine("");
305
+ writer.writeLine(d(n));
306
+ }
155
307
  }
156
308
  }
157
309
  }
package/source/index.ts CHANGED
@@ -6,6 +6,7 @@ export * from "./build_model_inner";
6
6
  export * from "./addExtensionObjectDataType";
7
7
  export * from "./symbol";
8
8
  export * from "./to_cvs";
9
+ export * from "./to_graphivz";
9
10
  export * from "./generate_markdown_doc";
10
11
  //
11
12
  export * from "node-opcua-address-space";
@@ -20,6 +21,7 @@ export * from "node-opcua-basic-types";
20
21
  export * from "node-opcua-constants";
21
22
  export * from "node-opcua-assert";
22
23
  export * from "node-opcua-service-translate-browse-path";
24
+
23
25
  export { MethodIds, DataTypeIds, ReferenceTypeIds, VariableIds, VariableTypeIds, ObjectTypeIds, ObjectIds } from "node-opcua-constants";
24
26
 
25
27
  export {