node-opcua-modeler 2.64.1 → 2.66.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.
- package/dist/addExtensionObjectDataType.d.ts +21 -21
- package/dist/addExtensionObjectDataType.js +130 -130
- package/dist/build_model_inner.d.ts +17 -17
- package/dist/build_model_inner.js +40 -40
- package/dist/build_model_inner.js.map +1 -1
- package/dist/displayNodeElement.d.ts +5 -5
- package/dist/displayNodeElement.js +192 -191
- package/dist/displayNodeElement.js.map +1 -1
- package/dist/dump_state_machine_to_graphviz.d.ts +6 -6
- package/dist/dump_state_machine_to_graphviz.js +119 -119
- package/dist/generate_markdown_doc.d.ts +41 -6
- package/dist/generate_markdown_doc.js +314 -266
- package/dist/generate_markdown_doc.js.map +1 -1
- package/dist/index.d.ts +24 -24
- package/dist/index.js +52 -48
- package/dist/index.js.map +1 -1
- package/dist/promoteToMandatory.d.ts +8 -8
- package/dist/promoteToMandatory.js +97 -97
- package/dist/setNamespaceMetaData.d.ts +1 -1
- package/dist/setNamespaceMetaData.js +5 -5
- package/dist/symbol.d.ts +1 -1
- package/dist/symbol.js +2 -2
- package/dist/tableHelper.d.ts +9 -9
- package/dist/tableHelper.js +60 -60
- package/dist/to_cvs.d.ts +2 -2
- package/dist/to_cvs.js +11 -11
- package/dist/to_graphivz.d.ts +14 -14
- package/dist/to_graphivz.js +294 -294
- package/dist/types.d.ts +1 -1
- package/dist/types.js +2 -2
- package/distNodeJS/build_documentation_to_file.d.ts +3 -2
- package/distNodeJS/build_documentation_to_file.js +26 -26
- package/distNodeJS/build_documentation_to_file.js.map +1 -1
- package/distNodeJS/build_model.d.ts +7 -7
- package/distNodeJS/build_model.js +21 -21
- package/distNodeJS/index.d.ts +5 -5
- package/distNodeJS/index.js +23 -19
- package/distNodeJS/index.js.map +1 -1
- package/distNodeJS/symbol_cvs.d.ts +3 -3
- package/distNodeJS/symbol_cvs.js +63 -63
- package/package.json +20 -20
- package/source/build_model_inner.ts +3 -5
- package/source/displayNodeElement.ts +3 -3
- package/source/generate_markdown_doc.ts +88 -33
- package/source/index.ts +2 -1
- package/source_nodejs/build_documentation_to_file.ts +3 -3
- package/MyModel.NodeSet2.xml +0 -125
- package/dist/buildModel.d.ts +0 -16
- package/dist/buildModel.js +0 -91
- package/dist/buildModel.js.map +0 -1
- package/dist/display.d.ts +0 -2
- package/dist/display.js +0 -96
- package/dist/display.js.map +0 -1
- package/source/dump_state_machine_to_graphviz.ts +0 -164
- package/source/to_graphivz.ts +0 -351
package/dist/to_cvs.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toCSV = void 0;
|
|
4
|
-
function toCSV(arr) {
|
|
5
|
-
const line = [];
|
|
6
|
-
for (const [name, value, nodeClass] of arr) {
|
|
7
|
-
line.push([name, value, nodeClass].join(","));
|
|
8
|
-
}
|
|
9
|
-
return line.join("\n");
|
|
10
|
-
}
|
|
11
|
-
exports.toCSV = toCSV;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toCSV = void 0;
|
|
4
|
+
function toCSV(arr) {
|
|
5
|
+
const line = [];
|
|
6
|
+
for (const [name, value, nodeClass] of arr) {
|
|
7
|
+
line.push([name, value, nodeClass].join(","));
|
|
8
|
+
}
|
|
9
|
+
return line.join("\n");
|
|
10
|
+
}
|
|
11
|
+
exports.toCSV = toCSV;
|
|
12
12
|
//# sourceMappingURL=to_cvs.js.map
|
package/dist/to_graphivz.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { UAReferenceType, UADataType, UAObjectType, UAVariableType } from "node-opcua-address-space";
|
|
2
|
-
interface Options {
|
|
3
|
-
naked: boolean;
|
|
4
|
-
}
|
|
5
|
-
export declare function opcuaToDot(node: UAObjectType | UAVariableType, options?: Options): string;
|
|
6
|
-
export declare function dumpClassHierachry(typeNode: UAObjectType | UAVariableType | UADataType | UAReferenceType, options?: {
|
|
7
|
-
naked?: boolean;
|
|
8
|
-
depth?: number;
|
|
9
|
-
showBaseType?: boolean;
|
|
10
|
-
showSubType?: boolean;
|
|
11
|
-
}): string;
|
|
12
|
-
export declare function graphVizToPlantUml(str: string): string;
|
|
13
|
-
export declare function dumpTypeDiagram(namespace: any): string;
|
|
14
|
-
export {};
|
|
1
|
+
import { UAReferenceType, UADataType, UAObjectType, UAVariableType } from "node-opcua-address-space";
|
|
2
|
+
interface Options {
|
|
3
|
+
naked: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare function opcuaToDot(node: UAObjectType | UAVariableType, options?: Options): string;
|
|
6
|
+
export declare function dumpClassHierachry(typeNode: UAObjectType | UAVariableType | UADataType | UAReferenceType, options?: {
|
|
7
|
+
naked?: boolean;
|
|
8
|
+
depth?: number;
|
|
9
|
+
showBaseType?: boolean;
|
|
10
|
+
showSubType?: boolean;
|
|
11
|
+
}): string;
|
|
12
|
+
export declare function graphVizToPlantUml(str: string): string;
|
|
13
|
+
export declare function dumpTypeDiagram(namespace: any): string;
|
|
14
|
+
export {};
|
package/dist/to_graphivz.js
CHANGED
|
@@ -1,295 +1,295 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dumpTypeDiagram = exports.graphVizToPlantUml = exports.dumpClassHierachry = exports.opcuaToDot = void 0;
|
|
4
|
-
const node_opcua_address_space_1 = require("node-opcua-address-space");
|
|
5
|
-
const node_opcua_constants_1 = require("node-opcua-constants");
|
|
6
|
-
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
7
|
-
function e(str) {
|
|
8
|
-
return str.replace(/</g, "<").replace(/>/g, ">");
|
|
9
|
-
}
|
|
10
|
-
function innerText(node) {
|
|
11
|
-
var _a, _b;
|
|
12
|
-
const browseName = node.browseName.name;
|
|
13
|
-
const typeDefinition = (_b = (_a = node.typeDefinitionObj) === null || _a === void 0 ? void 0 : _a.browseName) === null || _b === void 0 ? void 0 : _b.name;
|
|
14
|
-
if (typeDefinition) {
|
|
15
|
-
return `[ label =< <FONT point-size="8" ><I>${typeDefinition}</I></FONT><BR/>${e(browseName)} >]`;
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
return `[label =< ${e(browseName)} >]`;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
function arrowHeadAttribute(reference) {
|
|
22
|
-
switch (reference.referenceType.value) {
|
|
23
|
-
case node_opcua_constants_1.ReferenceTypeIds.HasTypeDefinition:
|
|
24
|
-
return "normalnormal";
|
|
25
|
-
case node_opcua_constants_1.ReferenceTypeIds.HasComponent:
|
|
26
|
-
return "noneteetee";
|
|
27
|
-
case node_opcua_constants_1.ReferenceTypeIds.HasProperty:
|
|
28
|
-
return "nonetee";
|
|
29
|
-
case node_opcua_constants_1.ReferenceTypeIds.HasSubtype:
|
|
30
|
-
return "onormalonormal";
|
|
31
|
-
case node_opcua_constants_1.ReferenceTypeIds.HasModellingRule:
|
|
32
|
-
return "none";
|
|
33
|
-
default:
|
|
34
|
-
return "normal";
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
function arrowHead(reference) {
|
|
38
|
-
return `[arrowhead = ${arrowHeadAttribute(reference)}]`;
|
|
39
|
-
}
|
|
40
|
-
const regularShapes = {
|
|
41
|
-
ObjectType: '[shape=rectangle, style="filled" fillcolor="#e8edf7;0.75:#d2def0" gradientangle=275]',
|
|
42
|
-
VariableType: '[shape=rectangle, style="rounded,filled" fillcolor="#e8edf7;0.75:#d2def0" gradientangle=275]',
|
|
43
|
-
Object: ' [shape=rectangle, style="filled" fillcolor="#e8edf7"]',
|
|
44
|
-
Variable: '[shape=rectangle, style="filled,rounded" fillcolor="#e8edf7"]',
|
|
45
|
-
Method: '[shape=oval, style="filled" fillcolor="#e8edf7"]'
|
|
46
|
-
};
|
|
47
|
-
const regularShapesOptionals = {
|
|
48
|
-
ObjectType: '[shape=rectangle, style="filled,dashed" fillcolor="#e8edf7;0.75:#d2def0" gradientangle=275]',
|
|
49
|
-
VariableType: '[shape=rectangle, style="rounded,filled,dashed" fillcolor="#e8edf7;0.75:#d2def0" gradientangle=275]',
|
|
50
|
-
Object: ' [shape=rectangle, style="filled,dashed" fillcolor="#e8edf7"]',
|
|
51
|
-
Variable: '[shape=rectangle, style="filled,rounded,dashed" fillcolor="#e8edf7"]',
|
|
52
|
-
Method: '[shape=oval, style="filled,dashed" fillcolor="#e8edf7"]'
|
|
53
|
-
};
|
|
54
|
-
class NodeRegistry {
|
|
55
|
-
constructor() {
|
|
56
|
-
this.m = {};
|
|
57
|
-
this.invisibleNodes = [];
|
|
58
|
-
this.duplicated = {};
|
|
59
|
-
}
|
|
60
|
-
add(name, node) {
|
|
61
|
-
if (this.duplicated[name]) {
|
|
62
|
-
return; //throw new Error("Already included");
|
|
63
|
-
}
|
|
64
|
-
this.duplicated[name] = name;
|
|
65
|
-
const nodeClass = node_opcua_data_model_1.NodeClass[node.nodeClass];
|
|
66
|
-
this.m[nodeClass] = this.m[nodeClass] || [];
|
|
67
|
-
this.m[nodeClass].push({ name, node });
|
|
68
|
-
}
|
|
69
|
-
addInvisibleNode(name) {
|
|
70
|
-
this.invisibleNodes.push(name);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
function dumpNodeByNodeClass(str, nodeRegistry) {
|
|
74
|
-
for (const [className, listNode] of Object.entries(nodeRegistry.m)) {
|
|
75
|
-
if (listNode.length === 0) {
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
str.push(` ## -> ${className}`);
|
|
79
|
-
const mandatoryNodes = listNode.filter(({ name, node }) => !node.modellingRule || node.modellingRule.match(/Mandatory/));
|
|
80
|
-
const optionalNodes = listNode.filter(({ name, node }) => node.modellingRule && node.modellingRule.match(/Optional/));
|
|
81
|
-
if (mandatoryNodes.length > 0) {
|
|
82
|
-
str.push(` node [];`);
|
|
83
|
-
const decoration = regularShapes[className];
|
|
84
|
-
str.push(` node ${decoration};`);
|
|
85
|
-
for (const { name, node } of mandatoryNodes) {
|
|
86
|
-
str.push(` ${name} ${innerText(node)}`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (optionalNodes.length > 0) {
|
|
90
|
-
const decoration2 = regularShapesOptionals[className];
|
|
91
|
-
str.push(` node [];`);
|
|
92
|
-
str.push(` node ${decoration2};`);
|
|
93
|
-
for (const { name, node } of listNode) {
|
|
94
|
-
str.push(` ${name} ${innerText(node)}`);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
if (nodeRegistry.invisibleNodes.length) {
|
|
99
|
-
str.push(" # invisible nodes");
|
|
100
|
-
str.push(" node []");
|
|
101
|
-
str.push(" node [width=0,height=0,shape=point,style=invis];");
|
|
102
|
-
str.push(` ${nodeRegistry.invisibleNodes.join("\n ")};`);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
const dump_state_machine_to_graphviz_1 = require("./dump_state_machine_to_graphviz");
|
|
106
|
-
function opcuaToDot(node, options) {
|
|
107
|
-
if (node.nodeClass === node_opcua_data_model_1.NodeClass.ObjectType) {
|
|
108
|
-
const finitieStateMachineType = node.addressSpace.findObjectType("FiniteStateMachineType");
|
|
109
|
-
if (finitieStateMachineType) {
|
|
110
|
-
if (node.isSupertypeOf(finitieStateMachineType)) {
|
|
111
|
-
const stateMachine = node.instantiate({ browseName: "StateMachine" });
|
|
112
|
-
(0, node_opcua_address_space_1.promoteToStateMachine)(stateMachine);
|
|
113
|
-
return (0, dump_state_machine_to_graphviz_1.dumpStateMachineToPlantUML)(stateMachine);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
options = options || { naked: false };
|
|
118
|
-
const nodeRegistry = new NodeRegistry();
|
|
119
|
-
const str = [];
|
|
120
|
-
const str2 = [];
|
|
121
|
-
str.push("digraph G {");
|
|
122
|
-
if (!options.naked) {
|
|
123
|
-
str.push(" rankdir=TB;");
|
|
124
|
-
str.push(" nodesep=0.5;");
|
|
125
|
-
str.push(" node [];");
|
|
126
|
-
}
|
|
127
|
-
function makeId(p, c) {
|
|
128
|
-
return `${p}_${c}`.replace(" ", "_").replace(/<|>/g, "_");
|
|
129
|
-
}
|
|
130
|
-
// eslint-disable-next-line max-params
|
|
131
|
-
// eslint-disable-next-line max-statements
|
|
132
|
-
function typeMemberAndSubTypeMember(str, parentNode, node, parent, offset, prefix, joinWithCaller, visitorMap) {
|
|
133
|
-
let innerDepth = 0;
|
|
134
|
-
const browseName = (parent || node).browseName.name.toString();
|
|
135
|
-
const r = [];
|
|
136
|
-
const r2 = [];
|
|
137
|
-
const references = (parent || node).findReferencesEx("Aggregates", node_opcua_data_model_1.BrowseDirection.Forward);
|
|
138
|
-
const folderElements = (parent || node).findReferencesEx("Organizes", node_opcua_data_model_1.BrowseDirection.Forward);
|
|
139
|
-
const childReferences = [...references, ...folderElements];
|
|
140
|
-
const id = makeId(parentNode, browseName);
|
|
141
|
-
nodeRegistry.add(id, node);
|
|
142
|
-
function addInvisibleNode(prefix, index) {
|
|
143
|
-
const breakNode = `${prefix}${index}`;
|
|
144
|
-
r2.push(breakNode);
|
|
145
|
-
nodeRegistry.addInvisibleNode(breakNode);
|
|
146
|
-
return breakNode;
|
|
147
|
-
}
|
|
148
|
-
for (let i = 0; i < childReferences.length; i++) {
|
|
149
|
-
const isLast = i === childReferences.length - 1;
|
|
150
|
-
const reference = childReferences[i];
|
|
151
|
-
const childNode = reference.node;
|
|
152
|
-
const childName = childNode.browseName.name.toString();
|
|
153
|
-
const fullChildName = makeId(id, childName);
|
|
154
|
-
// avoid member duplication
|
|
155
|
-
if (visitorMap[fullChildName]) {
|
|
156
|
-
continue;
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
visitorMap[fullChildName] = 1;
|
|
160
|
-
}
|
|
161
|
-
innerDepth++;
|
|
162
|
-
nodeRegistry.add(fullChildName, childNode);
|
|
163
|
-
const edgeAttributes = arrowHead(reference);
|
|
164
|
-
const breakNode = addInvisibleNode(prefix, i + offset);
|
|
165
|
-
const horizontalPart = `{ rank=same ${breakNode} -> ${fullChildName} ${edgeAttributes} }`;
|
|
166
|
-
r.push(horizontalPart);
|
|
167
|
-
// push children on same level
|
|
168
|
-
const [depth] = typeMemberAndSubTypeMember(str, id, childNode, null, 0, `${prefix}${i + offset}_`, false, visitorMap);
|
|
169
|
-
// add invisible nodes
|
|
170
|
-
{
|
|
171
|
-
for (let d = 0; d < depth; d++) {
|
|
172
|
-
offset++;
|
|
173
|
-
if (!isLast) {
|
|
174
|
-
addInvisibleNode(prefix, i + offset);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
innerDepth += depth;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
if (node.nodeClass == node_opcua_data_model_1.NodeClass.ObjectType || node.nodeClass === node_opcua_data_model_1.NodeClass.VariableType) {
|
|
181
|
-
if (node.subtypeOfObj && node.subtypeOfObj.nodeId.namespace === node.nodeId.namespace) {
|
|
182
|
-
const [depth, rr2] = typeMemberAndSubTypeMember(str, parentNode, node.subtypeOfObj, node, r.length + offset + 1, prefix, true, visitorMap);
|
|
183
|
-
innerDepth += depth + 1;
|
|
184
|
-
r2.push(...rr2);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
if (r.length) {
|
|
188
|
-
str.push(...r.map((x) => " " + x));
|
|
189
|
-
}
|
|
190
|
-
if (!joinWithCaller) {
|
|
191
|
-
if (r2.length) {
|
|
192
|
-
str.push(` ${id} -> ${r2.join(" -> ")} [arrowhead=none];`);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
return [innerDepth, r2];
|
|
196
|
-
}
|
|
197
|
-
const visitorMap = {};
|
|
198
|
-
typeMemberAndSubTypeMember(str2, "", node, null, 0, "r", false, visitorMap);
|
|
199
|
-
if (!options.naked) {
|
|
200
|
-
dumpNodeByNodeClass(str, nodeRegistry);
|
|
201
|
-
}
|
|
202
|
-
str.push(...str2);
|
|
203
|
-
str.push("}");
|
|
204
|
-
//
|
|
205
|
-
const dot = str.join("\n");
|
|
206
|
-
return dot;
|
|
207
|
-
}
|
|
208
|
-
exports.opcuaToDot = opcuaToDot;
|
|
209
|
-
function dumpClassHierachry(typeNode, options) {
|
|
210
|
-
options = options || { naked: false, showBaseType: true, showSubType: true };
|
|
211
|
-
const level = options.depth || 50;
|
|
212
|
-
const str = [];
|
|
213
|
-
const nodeRegistry = new NodeRegistry();
|
|
214
|
-
nodeRegistry.add(typeNode.browseName.name, typeNode);
|
|
215
|
-
str.push("digraph G {");
|
|
216
|
-
if (!options.naked) {
|
|
217
|
-
// str.push(" splines=ortho;");
|
|
218
|
-
str.push(" rankdir=BT;");
|
|
219
|
-
str.push(" nodesep=0.5;");
|
|
220
|
-
str.push(" node [];");
|
|
221
|
-
}
|
|
222
|
-
function dumpSubtypes(str, typeNode, level) {
|
|
223
|
-
const parentName = typeNode.browseName.name.toString();
|
|
224
|
-
const references = typeNode.findReferencesEx("HasSubtype", node_opcua_data_model_1.BrowseDirection.Forward);
|
|
225
|
-
for (let i = 0; i < references.length; i++) {
|
|
226
|
-
const reference = references[i];
|
|
227
|
-
const childNode = reference.node;
|
|
228
|
-
const nodeClass = node_opcua_data_model_1.NodeClass[childNode.nodeClass];
|
|
229
|
-
const childName = childNode.browseName.name.toString();
|
|
230
|
-
nodeRegistry.add(childName, childNode);
|
|
231
|
-
const edgeAttributes = arrowHead(reference);
|
|
232
|
-
str.push(` ${childName} -> ${parentName} ${edgeAttributes};`);
|
|
233
|
-
if (level > 0) {
|
|
234
|
-
dumpSubtypes(str, childNode, level - 1);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
function dumpBaseTypes(str, typeNode, level) {
|
|
239
|
-
const parentName = typeNode.browseName.name.toString();
|
|
240
|
-
const references = typeNode.findReferencesEx("HasSubtype", node_opcua_data_model_1.BrowseDirection.Inverse);
|
|
241
|
-
for (let i = 0; i < references.length; i++) {
|
|
242
|
-
const reference = references[i];
|
|
243
|
-
const childNode = reference.node;
|
|
244
|
-
const nodeClass = node_opcua_data_model_1.NodeClass[childNode.nodeClass];
|
|
245
|
-
const childName = childNode.browseName.name.toString();
|
|
246
|
-
nodeRegistry.add(childName, childNode);
|
|
247
|
-
const edgeAttributes = arrowHead(reference);
|
|
248
|
-
str.push(` ${parentName} -> ${childName} ${edgeAttributes};`);
|
|
249
|
-
if (level > 0) {
|
|
250
|
-
dumpBaseTypes(str, childNode, level - 1);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
const str2 = [];
|
|
255
|
-
if (options.showBaseType) {
|
|
256
|
-
dumpBaseTypes(str2, typeNode, level);
|
|
257
|
-
}
|
|
258
|
-
/** */
|
|
259
|
-
if (options.showSubType) {
|
|
260
|
-
dumpSubtypes(str2, typeNode, level);
|
|
261
|
-
}
|
|
262
|
-
if (!options.naked) {
|
|
263
|
-
dumpNodeByNodeClass(str, nodeRegistry);
|
|
264
|
-
}
|
|
265
|
-
str.push(...str2);
|
|
266
|
-
str.push("}");
|
|
267
|
-
return str.join("\n");
|
|
268
|
-
}
|
|
269
|
-
exports.dumpClassHierachry = dumpClassHierachry;
|
|
270
|
-
function graphVizToPlantUml(str) {
|
|
271
|
-
const ttt = "```";
|
|
272
|
-
return `${ttt}plantuml\n@startuml\n${str}\n@enduml\n${ttt}`;
|
|
273
|
-
}
|
|
274
|
-
exports.graphVizToPlantUml = graphVizToPlantUml;
|
|
275
|
-
function dumpTypeDiagram(namespace) {
|
|
276
|
-
const objectTypes = [...namespace._objectTypeIterator()];
|
|
277
|
-
const variableTypes = [...namespace._variableTypeIterator()];
|
|
278
|
-
const dataTypes = [...namespace._dataTypeIterator()];
|
|
279
|
-
const referenceTypes = [...namespace._referenceTypeIterator()];
|
|
280
|
-
const addressSpace = namespace.addressSpace;
|
|
281
|
-
const str = [];
|
|
282
|
-
for (const type of [...objectTypes, ...variableTypes]) {
|
|
283
|
-
const d = opcuaToDot(type);
|
|
284
|
-
str.push(graphVizToPlantUml(d));
|
|
285
|
-
const d2 = dumpClassHierachry(type);
|
|
286
|
-
str.push(graphVizToPlantUml(d2));
|
|
287
|
-
}
|
|
288
|
-
for (const dataType of dataTypes) {
|
|
289
|
-
const d = opcuaToDot(dataType);
|
|
290
|
-
str.push(graphVizToPlantUml(d));
|
|
291
|
-
}
|
|
292
|
-
return str.join("\n");
|
|
293
|
-
}
|
|
294
|
-
exports.dumpTypeDiagram = dumpTypeDiagram;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dumpTypeDiagram = exports.graphVizToPlantUml = exports.dumpClassHierachry = exports.opcuaToDot = void 0;
|
|
4
|
+
const node_opcua_address_space_1 = require("node-opcua-address-space");
|
|
5
|
+
const node_opcua_constants_1 = require("node-opcua-constants");
|
|
6
|
+
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
7
|
+
function e(str) {
|
|
8
|
+
return str.replace(/</g, "<").replace(/>/g, ">");
|
|
9
|
+
}
|
|
10
|
+
function innerText(node) {
|
|
11
|
+
var _a, _b;
|
|
12
|
+
const browseName = node.browseName.name;
|
|
13
|
+
const typeDefinition = (_b = (_a = node.typeDefinitionObj) === null || _a === void 0 ? void 0 : _a.browseName) === null || _b === void 0 ? void 0 : _b.name;
|
|
14
|
+
if (typeDefinition) {
|
|
15
|
+
return `[ label =< <FONT point-size="8" ><I>${typeDefinition}</I></FONT><BR/>${e(browseName)} >]`;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
return `[label =< ${e(browseName)} >]`;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function arrowHeadAttribute(reference) {
|
|
22
|
+
switch (reference.referenceType.value) {
|
|
23
|
+
case node_opcua_constants_1.ReferenceTypeIds.HasTypeDefinition:
|
|
24
|
+
return "normalnormal";
|
|
25
|
+
case node_opcua_constants_1.ReferenceTypeIds.HasComponent:
|
|
26
|
+
return "noneteetee";
|
|
27
|
+
case node_opcua_constants_1.ReferenceTypeIds.HasProperty:
|
|
28
|
+
return "nonetee";
|
|
29
|
+
case node_opcua_constants_1.ReferenceTypeIds.HasSubtype:
|
|
30
|
+
return "onormalonormal";
|
|
31
|
+
case node_opcua_constants_1.ReferenceTypeIds.HasModellingRule:
|
|
32
|
+
return "none";
|
|
33
|
+
default:
|
|
34
|
+
return "normal";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function arrowHead(reference) {
|
|
38
|
+
return `[arrowhead = ${arrowHeadAttribute(reference)}]`;
|
|
39
|
+
}
|
|
40
|
+
const regularShapes = {
|
|
41
|
+
ObjectType: '[shape=rectangle, style="filled" fillcolor="#e8edf7;0.75:#d2def0" gradientangle=275]',
|
|
42
|
+
VariableType: '[shape=rectangle, style="rounded,filled" fillcolor="#e8edf7;0.75:#d2def0" gradientangle=275]',
|
|
43
|
+
Object: ' [shape=rectangle, style="filled" fillcolor="#e8edf7"]',
|
|
44
|
+
Variable: '[shape=rectangle, style="filled,rounded" fillcolor="#e8edf7"]',
|
|
45
|
+
Method: '[shape=oval, style="filled" fillcolor="#e8edf7"]'
|
|
46
|
+
};
|
|
47
|
+
const regularShapesOptionals = {
|
|
48
|
+
ObjectType: '[shape=rectangle, style="filled,dashed" fillcolor="#e8edf7;0.75:#d2def0" gradientangle=275]',
|
|
49
|
+
VariableType: '[shape=rectangle, style="rounded,filled,dashed" fillcolor="#e8edf7;0.75:#d2def0" gradientangle=275]',
|
|
50
|
+
Object: ' [shape=rectangle, style="filled,dashed" fillcolor="#e8edf7"]',
|
|
51
|
+
Variable: '[shape=rectangle, style="filled,rounded,dashed" fillcolor="#e8edf7"]',
|
|
52
|
+
Method: '[shape=oval, style="filled,dashed" fillcolor="#e8edf7"]'
|
|
53
|
+
};
|
|
54
|
+
class NodeRegistry {
|
|
55
|
+
constructor() {
|
|
56
|
+
this.m = {};
|
|
57
|
+
this.invisibleNodes = [];
|
|
58
|
+
this.duplicated = {};
|
|
59
|
+
}
|
|
60
|
+
add(name, node) {
|
|
61
|
+
if (this.duplicated[name]) {
|
|
62
|
+
return; //throw new Error("Already included");
|
|
63
|
+
}
|
|
64
|
+
this.duplicated[name] = name;
|
|
65
|
+
const nodeClass = node_opcua_data_model_1.NodeClass[node.nodeClass];
|
|
66
|
+
this.m[nodeClass] = this.m[nodeClass] || [];
|
|
67
|
+
this.m[nodeClass].push({ name, node });
|
|
68
|
+
}
|
|
69
|
+
addInvisibleNode(name) {
|
|
70
|
+
this.invisibleNodes.push(name);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function dumpNodeByNodeClass(str, nodeRegistry) {
|
|
74
|
+
for (const [className, listNode] of Object.entries(nodeRegistry.m)) {
|
|
75
|
+
if (listNode.length === 0) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
str.push(` ## -> ${className}`);
|
|
79
|
+
const mandatoryNodes = listNode.filter(({ name, node }) => !node.modellingRule || node.modellingRule.match(/Mandatory/));
|
|
80
|
+
const optionalNodes = listNode.filter(({ name, node }) => node.modellingRule && node.modellingRule.match(/Optional/));
|
|
81
|
+
if (mandatoryNodes.length > 0) {
|
|
82
|
+
str.push(` node [];`);
|
|
83
|
+
const decoration = regularShapes[className];
|
|
84
|
+
str.push(` node ${decoration};`);
|
|
85
|
+
for (const { name, node } of mandatoryNodes) {
|
|
86
|
+
str.push(` ${name} ${innerText(node)}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (optionalNodes.length > 0) {
|
|
90
|
+
const decoration2 = regularShapesOptionals[className];
|
|
91
|
+
str.push(` node [];`);
|
|
92
|
+
str.push(` node ${decoration2};`);
|
|
93
|
+
for (const { name, node } of listNode) {
|
|
94
|
+
str.push(` ${name} ${innerText(node)}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (nodeRegistry.invisibleNodes.length) {
|
|
99
|
+
str.push(" # invisible nodes");
|
|
100
|
+
str.push(" node []");
|
|
101
|
+
str.push(" node [width=0,height=0,shape=point,style=invis];");
|
|
102
|
+
str.push(` ${nodeRegistry.invisibleNodes.join("\n ")};`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const dump_state_machine_to_graphviz_1 = require("./dump_state_machine_to_graphviz");
|
|
106
|
+
function opcuaToDot(node, options) {
|
|
107
|
+
if (node.nodeClass === node_opcua_data_model_1.NodeClass.ObjectType) {
|
|
108
|
+
const finitieStateMachineType = node.addressSpace.findObjectType("FiniteStateMachineType");
|
|
109
|
+
if (finitieStateMachineType) {
|
|
110
|
+
if (node.isSupertypeOf(finitieStateMachineType)) {
|
|
111
|
+
const stateMachine = node.instantiate({ browseName: "StateMachine" });
|
|
112
|
+
(0, node_opcua_address_space_1.promoteToStateMachine)(stateMachine);
|
|
113
|
+
return (0, dump_state_machine_to_graphviz_1.dumpStateMachineToPlantUML)(stateMachine);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
options = options || { naked: false };
|
|
118
|
+
const nodeRegistry = new NodeRegistry();
|
|
119
|
+
const str = [];
|
|
120
|
+
const str2 = [];
|
|
121
|
+
str.push("digraph G {");
|
|
122
|
+
if (!options.naked) {
|
|
123
|
+
str.push(" rankdir=TB;");
|
|
124
|
+
str.push(" nodesep=0.5;");
|
|
125
|
+
str.push(" node [];");
|
|
126
|
+
}
|
|
127
|
+
function makeId(p, c) {
|
|
128
|
+
return `${p}_${c}`.replace(" ", "_").replace(/<|>/g, "_");
|
|
129
|
+
}
|
|
130
|
+
// eslint-disable-next-line max-params
|
|
131
|
+
// eslint-disable-next-line max-statements
|
|
132
|
+
function typeMemberAndSubTypeMember(str, parentNode, node, parent, offset, prefix, joinWithCaller, visitorMap) {
|
|
133
|
+
let innerDepth = 0;
|
|
134
|
+
const browseName = (parent || node).browseName.name.toString();
|
|
135
|
+
const r = [];
|
|
136
|
+
const r2 = [];
|
|
137
|
+
const references = (parent || node).findReferencesEx("Aggregates", node_opcua_data_model_1.BrowseDirection.Forward);
|
|
138
|
+
const folderElements = (parent || node).findReferencesEx("Organizes", node_opcua_data_model_1.BrowseDirection.Forward);
|
|
139
|
+
const childReferences = [...references, ...folderElements];
|
|
140
|
+
const id = makeId(parentNode, browseName);
|
|
141
|
+
nodeRegistry.add(id, node);
|
|
142
|
+
function addInvisibleNode(prefix, index) {
|
|
143
|
+
const breakNode = `${prefix}${index}`;
|
|
144
|
+
r2.push(breakNode);
|
|
145
|
+
nodeRegistry.addInvisibleNode(breakNode);
|
|
146
|
+
return breakNode;
|
|
147
|
+
}
|
|
148
|
+
for (let i = 0; i < childReferences.length; i++) {
|
|
149
|
+
const isLast = i === childReferences.length - 1;
|
|
150
|
+
const reference = childReferences[i];
|
|
151
|
+
const childNode = reference.node;
|
|
152
|
+
const childName = childNode.browseName.name.toString();
|
|
153
|
+
const fullChildName = makeId(id, childName);
|
|
154
|
+
// avoid member duplication
|
|
155
|
+
if (visitorMap[fullChildName]) {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
visitorMap[fullChildName] = 1;
|
|
160
|
+
}
|
|
161
|
+
innerDepth++;
|
|
162
|
+
nodeRegistry.add(fullChildName, childNode);
|
|
163
|
+
const edgeAttributes = arrowHead(reference);
|
|
164
|
+
const breakNode = addInvisibleNode(prefix, i + offset);
|
|
165
|
+
const horizontalPart = `{ rank=same ${breakNode} -> ${fullChildName} ${edgeAttributes} }`;
|
|
166
|
+
r.push(horizontalPart);
|
|
167
|
+
// push children on same level
|
|
168
|
+
const [depth] = typeMemberAndSubTypeMember(str, id, childNode, null, 0, `${prefix}${i + offset}_`, false, visitorMap);
|
|
169
|
+
// add invisible nodes
|
|
170
|
+
{
|
|
171
|
+
for (let d = 0; d < depth; d++) {
|
|
172
|
+
offset++;
|
|
173
|
+
if (!isLast) {
|
|
174
|
+
addInvisibleNode(prefix, i + offset);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
innerDepth += depth;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (node.nodeClass == node_opcua_data_model_1.NodeClass.ObjectType || node.nodeClass === node_opcua_data_model_1.NodeClass.VariableType) {
|
|
181
|
+
if (node.subtypeOfObj && node.subtypeOfObj.nodeId.namespace === node.nodeId.namespace) {
|
|
182
|
+
const [depth, rr2] = typeMemberAndSubTypeMember(str, parentNode, node.subtypeOfObj, node, r.length + offset + 1, prefix, true, visitorMap);
|
|
183
|
+
innerDepth += depth + 1;
|
|
184
|
+
r2.push(...rr2);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (r.length) {
|
|
188
|
+
str.push(...r.map((x) => " " + x));
|
|
189
|
+
}
|
|
190
|
+
if (!joinWithCaller) {
|
|
191
|
+
if (r2.length) {
|
|
192
|
+
str.push(` ${id} -> ${r2.join(" -> ")} [arrowhead=none];`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return [innerDepth, r2];
|
|
196
|
+
}
|
|
197
|
+
const visitorMap = {};
|
|
198
|
+
typeMemberAndSubTypeMember(str2, "", node, null, 0, "r", false, visitorMap);
|
|
199
|
+
if (!options.naked) {
|
|
200
|
+
dumpNodeByNodeClass(str, nodeRegistry);
|
|
201
|
+
}
|
|
202
|
+
str.push(...str2);
|
|
203
|
+
str.push("}");
|
|
204
|
+
//
|
|
205
|
+
const dot = str.join("\n");
|
|
206
|
+
return dot;
|
|
207
|
+
}
|
|
208
|
+
exports.opcuaToDot = opcuaToDot;
|
|
209
|
+
function dumpClassHierachry(typeNode, options) {
|
|
210
|
+
options = options || { naked: false, showBaseType: true, showSubType: true };
|
|
211
|
+
const level = options.depth || 50;
|
|
212
|
+
const str = [];
|
|
213
|
+
const nodeRegistry = new NodeRegistry();
|
|
214
|
+
nodeRegistry.add(typeNode.browseName.name, typeNode);
|
|
215
|
+
str.push("digraph G {");
|
|
216
|
+
if (!options.naked) {
|
|
217
|
+
// str.push(" splines=ortho;");
|
|
218
|
+
str.push(" rankdir=BT;");
|
|
219
|
+
str.push(" nodesep=0.5;");
|
|
220
|
+
str.push(" node [];");
|
|
221
|
+
}
|
|
222
|
+
function dumpSubtypes(str, typeNode, level) {
|
|
223
|
+
const parentName = typeNode.browseName.name.toString();
|
|
224
|
+
const references = typeNode.findReferencesEx("HasSubtype", node_opcua_data_model_1.BrowseDirection.Forward);
|
|
225
|
+
for (let i = 0; i < references.length; i++) {
|
|
226
|
+
const reference = references[i];
|
|
227
|
+
const childNode = reference.node;
|
|
228
|
+
const nodeClass = node_opcua_data_model_1.NodeClass[childNode.nodeClass];
|
|
229
|
+
const childName = childNode.browseName.name.toString();
|
|
230
|
+
nodeRegistry.add(childName, childNode);
|
|
231
|
+
const edgeAttributes = arrowHead(reference);
|
|
232
|
+
str.push(` ${childName} -> ${parentName} ${edgeAttributes};`);
|
|
233
|
+
if (level > 0) {
|
|
234
|
+
dumpSubtypes(str, childNode, level - 1);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
function dumpBaseTypes(str, typeNode, level) {
|
|
239
|
+
const parentName = typeNode.browseName.name.toString();
|
|
240
|
+
const references = typeNode.findReferencesEx("HasSubtype", node_opcua_data_model_1.BrowseDirection.Inverse);
|
|
241
|
+
for (let i = 0; i < references.length; i++) {
|
|
242
|
+
const reference = references[i];
|
|
243
|
+
const childNode = reference.node;
|
|
244
|
+
const nodeClass = node_opcua_data_model_1.NodeClass[childNode.nodeClass];
|
|
245
|
+
const childName = childNode.browseName.name.toString();
|
|
246
|
+
nodeRegistry.add(childName, childNode);
|
|
247
|
+
const edgeAttributes = arrowHead(reference);
|
|
248
|
+
str.push(` ${parentName} -> ${childName} ${edgeAttributes};`);
|
|
249
|
+
if (level > 0) {
|
|
250
|
+
dumpBaseTypes(str, childNode, level - 1);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
const str2 = [];
|
|
255
|
+
if (options.showBaseType) {
|
|
256
|
+
dumpBaseTypes(str2, typeNode, level);
|
|
257
|
+
}
|
|
258
|
+
/** */
|
|
259
|
+
if (options.showSubType) {
|
|
260
|
+
dumpSubtypes(str2, typeNode, level);
|
|
261
|
+
}
|
|
262
|
+
if (!options.naked) {
|
|
263
|
+
dumpNodeByNodeClass(str, nodeRegistry);
|
|
264
|
+
}
|
|
265
|
+
str.push(...str2);
|
|
266
|
+
str.push("}");
|
|
267
|
+
return str.join("\n");
|
|
268
|
+
}
|
|
269
|
+
exports.dumpClassHierachry = dumpClassHierachry;
|
|
270
|
+
function graphVizToPlantUml(str) {
|
|
271
|
+
const ttt = "```";
|
|
272
|
+
return `${ttt}plantuml\n@startuml\n${str}\n@enduml\n${ttt}`;
|
|
273
|
+
}
|
|
274
|
+
exports.graphVizToPlantUml = graphVizToPlantUml;
|
|
275
|
+
function dumpTypeDiagram(namespace) {
|
|
276
|
+
const objectTypes = [...namespace._objectTypeIterator()];
|
|
277
|
+
const variableTypes = [...namespace._variableTypeIterator()];
|
|
278
|
+
const dataTypes = [...namespace._dataTypeIterator()];
|
|
279
|
+
const referenceTypes = [...namespace._referenceTypeIterator()];
|
|
280
|
+
const addressSpace = namespace.addressSpace;
|
|
281
|
+
const str = [];
|
|
282
|
+
for (const type of [...objectTypes, ...variableTypes]) {
|
|
283
|
+
const d = opcuaToDot(type);
|
|
284
|
+
str.push(graphVizToPlantUml(d));
|
|
285
|
+
const d2 = dumpClassHierachry(type);
|
|
286
|
+
str.push(graphVizToPlantUml(d2));
|
|
287
|
+
}
|
|
288
|
+
for (const dataType of dataTypes) {
|
|
289
|
+
const d = opcuaToDot(dataType);
|
|
290
|
+
str.push(graphVizToPlantUml(d));
|
|
291
|
+
}
|
|
292
|
+
return str.join("\n");
|
|
293
|
+
}
|
|
294
|
+
exports.dumpTypeDiagram = dumpTypeDiagram;
|
|
295
295
|
//# sourceMappingURL=to_graphivz.js.map
|
package/dist/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { UANamespaceMetadata } from "node-opcua-address-space";
|
|
1
|
+
export { UANamespaceMetadata } from "node-opcua-address-space";
|
package/dist/types.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
//# sourceMappingURL=types.js.map
|