@vitormnm/node-red-simple-opcua 1.4.3 → 1.5.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 (32) hide show
  1. package/client/icons/opcua.svg +132 -132
  2. package/client/lib/opcua-client-browser.js +368 -330
  3. package/client/lib/opcua-client-method-service.js +88 -88
  4. package/client/lib/opcua-client-read-service.js +15 -15
  5. package/client/lib/opcua-client-subscription-id-service.js +24 -24
  6. package/client/lib/opcua-client-subscription-service.js +170 -170
  7. package/client/lib/opcua-client-write-service.js +146 -146
  8. package/client/opcua-client-config.html +80 -80
  9. package/client/opcua-client-utils.js +12 -11
  10. package/client/opcua-client.html +140 -140
  11. package/client/view/opcua-client.js +1144 -1140
  12. package/icons/opcua.svg +132 -132
  13. package/icons/opcua2.svg +132 -132
  14. package/package.json +3 -3
  15. package/server/icons/opcua.svg +132 -132
  16. package/server/lib/opcua-address-space-alarm.js +341 -341
  17. package/server/lib/opcua-address-space-builder.js +1603 -1485
  18. package/server/lib/opcua-config.js +677 -546
  19. package/server/lib/opcua-constants.js +119 -109
  20. package/server/lib/opcua-server-events-child.js +139 -139
  21. package/server/lib/opcua-server-runtime-child.js +873 -819
  22. package/server/lib/opcua-server-runtime.js +376 -311
  23. package/server/lib/opcua-server-status-child.js +187 -187
  24. package/server/lib/server-node-utils.js +16 -16
  25. package/server/opcua-server-io.html +346 -346
  26. package/server/opcua-server-io.js +497 -496
  27. package/server/opcua-server-registry.js +270 -270
  28. package/server/opcua-server.css +265 -265
  29. package/server/opcua-server.html +155 -1643
  30. package/server/opcua-server.js +24 -13
  31. package/server/view/opcua-server.css +492 -0
  32. package/server/view/opcua-server.js +1435 -0
@@ -1,311 +1,376 @@
1
- "use strict";
2
-
3
-
4
-
5
- const {
6
- OPCUAServer,
7
- UserTokenType,
8
- buildApplicationUri
9
- } = require("./opcua-constants");
10
- const { OpcUaAddressSpaceBuilder } = require("./opcua-address-space-builder");
11
- const { OpcUaServerMethods } = require("./opcua-server-methods");
12
-
13
- class OpcUaServerRuntime {
14
- constructor(options) {
15
- this.node = options.node;
16
- this.registry = options.registry;
17
- this.id = options.settings.id;
18
- this.name = options.settings.name;
19
- this.serverName = options.settings.serverName;
20
- this.port = options.settings.port;
21
- this.maxConnections = options.settings.maxConnections;
22
- this.namespaceUri = options.settings.namespaceUri;
23
- this.resourcePath = options.settings.resourcePath;
24
- this.allowAnonymous = options.settings.allowAnonymous;
25
- this.users = options.settings.users;
26
- this.securityPolicy = options.settings.securityPolicy;
27
- this.securityMode = options.settings.securityMode;
28
- this.treeConfig = options.settings.treeConfig;
29
-
30
- this.server = null;
31
- this.namespace = null;
32
- this.namespaces = new Map();
33
- this.namespaceDefinitions = new Map();
34
- this.addressSpaceBuilder = null;
35
-
36
-
37
- }
38
-
39
- async start() {
40
- if (this.server) {
41
- return;
42
- }
43
-
44
- this.server = new OPCUAServer(this.buildServerOptions());
45
- await this.server.initialize();
46
-
47
- const addressSpace = this.server.engine.addressSpace;
48
-
49
- this.initializeNamespaces(this.treeConfig);
50
-
51
- this.addressSpaceBuilder = new OpcUaAddressSpaceBuilder({
52
- namespace: this.namespace,
53
- namespaces: this.namespaces,
54
- server: this.server,
55
- registry: this.registry,
56
- node: this.node,
57
- serverName: this.serverName,
58
- addressSpace: this.addressSpace
59
- });
60
-
61
-
62
- this.addressSpaceBuilder.rebuild(this.treeConfig);
63
- await this.server.start();
64
- this.registry.registerServer(this);
65
-
66
- //Methods
67
- const ServerMethods = new OpcUaServerMethods({
68
- addressSpace: addressSpace,
69
- registry: this.registry,
70
- node: this.node
71
- })
72
-
73
- ServerMethods.start();
74
-
75
-
76
- }
77
-
78
- async stop() {
79
- if (!this.server) {
80
- this.node.status({ fill: "grey", shape: "ring", text: "stopped" });
81
- return;
82
- }
83
-
84
- try {
85
- if (this.addressSpaceBuilder) {
86
- this.addressSpaceBuilder.clearDynamicNodes();
87
- this.addressSpaceBuilder.variableStore.clear();
88
- }
89
-
90
- await this.server.shutdown(1000);
91
- } finally {
92
- this.registry.unregisterServer(this.id);
93
- this.addressSpaceBuilder = null;
94
- this.namespace = null;
95
- this.namespaces = new Map();
96
- this.namespaceDefinitions = new Map();
97
- this.server = null;
98
- this.node.status({ fill: "grey", shape: "ring", text: "stopped" });
99
- }
100
- }
101
-
102
- ensureReady() {
103
- if (!this.server || !this.namespace || !this.addressSpaceBuilder) {
104
- throw new Error("OPC UA server is not available");
105
- }
106
- }
107
-
108
-
109
-
110
- async updateTree(treeConfig) {
111
- this.ensureReady();
112
- this.syncNamespaces(treeConfig);
113
- this.treeConfig = treeConfig;
114
- this.addressSpaceBuilder.sync(treeConfig);
115
- }
116
-
117
- readValueByPath(path) {
118
- this.ensureReady();
119
- return this.addressSpaceBuilder.readValueByPath(path);
120
- }
121
-
122
- readValueByNodeId(nodeId) {
123
- this.ensureReady();
124
- return this.addressSpaceBuilder.readValueByNodeId(nodeId);
125
- }
126
-
127
- readValue(identifierType, identifier) {
128
- this.ensureReady();
129
- return this.addressSpaceBuilder.readValue(identifierType, identifier);
130
- }
131
-
132
- writeEventByPath(valuesPayload) {
133
- this.ensureReady();
134
- return this.addressSpaceBuilder.eventValueByPath(valuesPayload);
135
- }
136
-
137
- writeValueByPath(path, value) {
138
- this.ensureReady();
139
- return this.addressSpaceBuilder.writeValueByPath(path, value);
140
- }
141
-
142
- writeValueByNodeId(nodeId, value) {
143
- this.ensureReady();
144
- return this.addressSpaceBuilder.writeValueByNodeId(nodeId, value);
145
- }
146
-
147
- writeValue(identifierType, identifier, value) {
148
- this.ensureReady();
149
- return this.addressSpaceBuilder.writeValue(identifierType, identifier, value);
150
- }
151
-
152
- getEndpointUrl() {
153
- if (!this.server || !Array.isArray(this.server.endpoints)) {
154
- return "";
155
- }
156
-
157
- for (let index = 0; index < this.server.endpoints.length; index += 1) {
158
- const endpoint = this.server.endpoints[index];
159
- if (!endpoint || typeof endpoint.endpointDescriptions !== "function") {
160
- continue;
161
- }
162
-
163
- const descriptions = endpoint.endpointDescriptions();
164
- if (Array.isArray(descriptions) && descriptions.length && descriptions[0].endpointUrl) {
165
- return descriptions[0].endpointUrl;
166
- }
167
- }
168
-
169
- return "opc.tcp://localhost:" + this.port + this.resourcePath;
170
- }
171
-
172
- buildServerOptions() {
173
- const activeUsers = Array.isArray(this.users) ? this.users : [];
174
- const userTokenPolicies = [];
175
-
176
- if (this.allowAnonymous) {
177
- userTokenPolicies.push({
178
- policyId: "anonymous",
179
- tokenType: UserTokenType.Anonymous
180
- });
181
- }
182
-
183
- if (activeUsers.length) {
184
- userTokenPolicies.push({
185
- policyId: "username",
186
- tokenType: UserTokenType.UserName
187
- });
188
- }
189
-
190
- return {
191
- port: this.port,
192
- resourcePath: this.resourcePath,
193
- buildInfo: {
194
- productName: "opc-ua-server",
195
- buildNumber: "1",
196
- buildDate: new Date()
197
- },
198
- // serverCertificateManager: {
199
- // automaticallyAcceptUnknownCertificate: true
200
- // },
201
- serverCapabilities: {
202
- maxSessions: this.maxConnections
203
- },
204
- serverInfo: {
205
- applicationName: { text: this.serverName },
206
- applicationUri: buildApplicationUri(this.serverName),
207
- productUri: "urn:node-red:opc-ua-server"
208
- },
209
- securityPolicies: [this.securityPolicy],
210
- securityModes: [this.securityMode],
211
- allowAnonymous: this.allowAnonymous,
212
- userManager: {
213
- isValidUser: (username, password) => this.isValidUser(username, password)
214
- },
215
- userTokenPolicies
216
- };
217
- }
218
-
219
- isValidUser(username, password) {
220
- return this.users.some((user) => {
221
- if (user.username !== username) {
222
- return false;
223
- }
224
-
225
- if (user.password && user.password === password) {
226
- return true;
227
- }
228
-
229
- if (user.passwordHash) {
230
- try {
231
- return bcrypt.compareSync(password, user.passwordHash);
232
- } catch (error) {
233
- this.node.warn("Failed to validate password hash for user " + username + ": " + error.message);
234
- return false;
235
- }
236
- }
237
-
238
- return false;
239
- });
240
- }
241
-
242
- initializeNamespaces(treeConfig) {
243
- const addressSpace = this.server.engine.addressSpace;
244
- const configuredNamespaces = this.buildNamespaceDefinitions(treeConfig);
245
-
246
- this.namespaces = new Map();
247
- this.namespaceDefinitions = configuredNamespaces;
248
-
249
- configuredNamespaces.forEach((uri, namespaceId) => {
250
- const namespace = addressSpace.getNamespace(uri) || addressSpace.registerNamespace(uri);
251
- this.namespaces.set(namespaceId, namespace);
252
- });
253
-
254
- this.namespace = this.namespaces.get(2);
255
- }
256
-
257
- syncNamespaces(treeConfig) {
258
- const addressSpace = this.server.engine.addressSpace;
259
- const nextDefinitions = this.buildNamespaceDefinitions(treeConfig);
260
-
261
- this.namespaceDefinitions.forEach((uri, namespaceId) => {
262
- const nextUri = nextDefinitions.get(namespaceId);
263
- if (nextUri && nextUri !== uri) {
264
- throw new Error("Namespace URI changes require a redeploy: namespace " + namespaceId);
265
- }
266
-
267
- if (!nextUri) {
268
- throw new Error("Removing namespaces requires a redeploy: namespace " + namespaceId);
269
- }
270
- });
271
-
272
- nextDefinitions.forEach((uri, namespaceId) => {
273
- if (this.namespaces.has(namespaceId)) {
274
- return;
275
- }
276
-
277
- const namespace = addressSpace.getNamespace(uri) || addressSpace.registerNamespace(uri);
278
- this.namespaces.set(namespaceId, namespace);
279
- });
280
-
281
- this.namespaceDefinitions = nextDefinitions;
282
- this.namespace = this.namespaces.get(2);
283
- }
284
-
285
- buildNamespaceDefinitions(treeConfig) {
286
- const definitions = new Map();
287
- const configuredNamespaces = Array.isArray(treeConfig && treeConfig.nameSpaces) ? treeConfig.nameSpaces : [];
288
- let defaultNamespaceUri = this.namespaceUri;
289
-
290
- configuredNamespaces.forEach((namespaceConfig) => {
291
- if (namespaceConfig.id === 2) {
292
- defaultNamespaceUri = namespaceConfig.name;
293
- }
294
- });
295
-
296
- definitions.set(2, defaultNamespaceUri);
297
-
298
- configuredNamespaces
299
- .slice()
300
- .sort((left, right) => left.id - right.id)
301
- .forEach((namespaceConfig) => {
302
- definitions.set(namespaceConfig.id, namespaceConfig.name);
303
- });
304
-
305
- return definitions;
306
- }
307
- }
308
-
309
- module.exports = {
310
- OpcUaServerRuntime
311
- };
1
+ "use strict";
2
+
3
+
4
+
5
+ const {
6
+ OPCUAServer,
7
+ UserTokenType,
8
+ buildApplicationUri,
9
+ makeRoles,
10
+ WellKnownRoles,
11
+ resolveNodeId
12
+ } = require("./opcua-constants");
13
+ const { OpcUaAddressSpaceBuilder } = require("./opcua-address-space-builder");
14
+ const { OpcUaServerMethods } = require("./opcua-server-methods");
15
+ let bcrypt = null;
16
+
17
+ try {
18
+ bcrypt = require("bcryptjs");
19
+ } catch (error) {
20
+ bcrypt = null;
21
+ }
22
+
23
+ class OpcUaServerRuntime {
24
+ constructor(options) {
25
+ this.node = options.node;
26
+ this.registry = options.registry;
27
+ this.id = options.settings.id;
28
+ this.name = options.settings.name;
29
+ this.serverName = options.settings.serverName;
30
+ this.port = options.settings.port;
31
+ this.maxConnections = options.settings.maxConnections;
32
+ this.namespaceUri = options.settings.namespaceUri;
33
+ this.resourcePath = options.settings.resourcePath;
34
+ this.allowAnonymous = options.settings.allowAnonymous;
35
+ this.groups = options.settings.groups;
36
+ this.users = options.settings.users;
37
+ this.securityPolicy = options.settings.securityPolicy;
38
+ this.securityMode = options.settings.securityMode;
39
+ this.treeConfig = options.settings.treeConfig;
40
+
41
+ this.server = null;
42
+ this.namespace = null;
43
+ this.namespaces = new Map();
44
+ this.namespaceDefinitions = new Map();
45
+ this.addressSpaceBuilder = null;
46
+
47
+
48
+ }
49
+
50
+ async start() {
51
+ if (this.server) {
52
+ return;
53
+ }
54
+
55
+ this.server = new OPCUAServer(this.buildServerOptions());
56
+ await this.server.initialize();
57
+
58
+ const addressSpace = this.server.engine.addressSpace;
59
+
60
+ this.initializeNamespaces(this.treeConfig);
61
+
62
+ this.addressSpaceBuilder = new OpcUaAddressSpaceBuilder({
63
+ namespace: this.namespace,
64
+ namespaces: this.namespaces,
65
+ server: this.server,
66
+ registry: this.registry,
67
+ node: this.node,
68
+ serverName: this.serverName,
69
+ addressSpace: this.addressSpace,
70
+ allowAnonymous: this.allowAnonymous
71
+ });
72
+
73
+
74
+ this.addressSpaceBuilder.rebuild(this.treeConfig);
75
+ await this.server.start();
76
+ this.registry.registerServer(this);
77
+
78
+ //Methods
79
+ const ServerMethods = new OpcUaServerMethods({
80
+ addressSpace: addressSpace,
81
+ registry: this.registry,
82
+ node: this.node
83
+ })
84
+
85
+ ServerMethods.start();
86
+
87
+
88
+ }
89
+
90
+ async stop() {
91
+ if (!this.server) {
92
+ this.node.status({ fill: "grey", shape: "ring", text: "stopped" });
93
+ return;
94
+ }
95
+
96
+ try {
97
+ if (this.addressSpaceBuilder) {
98
+ this.addressSpaceBuilder.clearDynamicNodes();
99
+ this.addressSpaceBuilder.variableStore.clear();
100
+ }
101
+
102
+ await this.server.shutdown(1000);
103
+ } finally {
104
+ this.registry.unregisterServer(this.id);
105
+ this.addressSpaceBuilder = null;
106
+ this.namespace = null;
107
+ this.namespaces = new Map();
108
+ this.namespaceDefinitions = new Map();
109
+ this.server = null;
110
+ this.node.status({ fill: "grey", shape: "ring", text: "stopped" });
111
+ }
112
+ }
113
+
114
+ ensureReady() {
115
+ if (!this.server || !this.namespace || !this.addressSpaceBuilder) {
116
+ throw new Error("OPC UA server is not available");
117
+ }
118
+ }
119
+
120
+
121
+
122
+ async updateTree(treeConfig) {
123
+ this.ensureReady();
124
+ this.syncNamespaces(treeConfig);
125
+ this.treeConfig = treeConfig;
126
+ this.addressSpaceBuilder.sync(treeConfig);
127
+ }
128
+
129
+ readValueByPath(path) {
130
+ this.ensureReady();
131
+ return this.addressSpaceBuilder.readValueByPath(path);
132
+ }
133
+
134
+ readValueByNodeId(nodeId) {
135
+ this.ensureReady();
136
+ return this.addressSpaceBuilder.readValueByNodeId(nodeId);
137
+ }
138
+
139
+ readValue(identifierType, identifier) {
140
+ this.ensureReady();
141
+ return this.addressSpaceBuilder.readValue(identifierType, identifier);
142
+ }
143
+
144
+ writeEventByPath(valuesPayload) {
145
+ this.ensureReady();
146
+ return this.addressSpaceBuilder.eventValueByPath(valuesPayload);
147
+ }
148
+
149
+ writeValueByPath(path, value) {
150
+ this.ensureReady();
151
+ return this.addressSpaceBuilder.writeValueByPath(path, value);
152
+ }
153
+
154
+ writeValueByNodeId(nodeId, value) {
155
+ this.ensureReady();
156
+ return this.addressSpaceBuilder.writeValueByNodeId(nodeId, value);
157
+ }
158
+
159
+ writeValue(identifierType, identifier, value) {
160
+ this.ensureReady();
161
+ return this.addressSpaceBuilder.writeValue(identifierType, identifier, value);
162
+ }
163
+
164
+ getEndpointUrl() {
165
+ if (!this.server || !Array.isArray(this.server.endpoints)) {
166
+ return "";
167
+ }
168
+
169
+ for (let index = 0; index < this.server.endpoints.length; index += 1) {
170
+ const endpoint = this.server.endpoints[index];
171
+ if (!endpoint || typeof endpoint.endpointDescriptions !== "function") {
172
+ continue;
173
+ }
174
+
175
+ const descriptions = endpoint.endpointDescriptions();
176
+ if (Array.isArray(descriptions) && descriptions.length && descriptions[0].endpointUrl) {
177
+ return descriptions[0].endpointUrl;
178
+ }
179
+ }
180
+
181
+ return "opc.tcp://localhost:" + this.port + this.resourcePath;
182
+ }
183
+
184
+ buildServerOptions() {
185
+ const activeUsers = Array.isArray(this.users) ? this.users : [];
186
+ const userTokenPolicies = [];
187
+
188
+ if (this.allowAnonymous) {
189
+ userTokenPolicies.push({
190
+ policyId: "anonymous",
191
+ tokenType: UserTokenType.Anonymous
192
+ });
193
+ }
194
+
195
+ if (activeUsers.length) {
196
+ userTokenPolicies.push({
197
+ policyId: "username",
198
+ tokenType: UserTokenType.UserName
199
+ });
200
+ }
201
+
202
+ return {
203
+ port: this.port,
204
+ resourcePath: this.resourcePath,
205
+ buildInfo: {
206
+ productName: "opc-ua-server",
207
+ buildNumber: "1",
208
+ buildDate: new Date()
209
+ },
210
+ serverCapabilities: {
211
+ maxSessions: this.maxConnections
212
+ },
213
+ serverInfo: {
214
+ applicationName: { text: this.serverName },
215
+ applicationUri: buildApplicationUri(this.serverName),
216
+ productUri: "urn:node-red:opc-ua-server"
217
+ },
218
+ securityPolicies: [this.securityPolicy],
219
+ securityModes: [this.securityMode],
220
+ allowAnonymous: this.allowAnonymous,
221
+ userManager: {
222
+ isValidUser: (username, password) => this.isValidUser(username, password),
223
+ getUserRoles: (username) => this.getUserRoles(username)
224
+ },
225
+ userTokenPolicies
226
+ };
227
+ }
228
+
229
+ getUserRoles(username) {
230
+ const normalizedUserName = typeof username === "string" ? username.trim() : "";
231
+ if (!normalizedUserName || normalizedUserName.toLowerCase() === "anonymous") {
232
+ return makeRoles([WellKnownRoles.Anonymous]);
233
+ }
234
+
235
+ const user = this.users.find((entry) => entry && entry.username === normalizedUserName);
236
+ if (!user) {
237
+ return makeRoles([WellKnownRoles.AuthenticatedUser]);
238
+ }
239
+
240
+ const roles = [resolveNodeId("WellKnownRole_AuthenticatedUser")];
241
+ const customRole = this.resolveGroupRoleNodeId(user.group);
242
+ if (customRole) {
243
+ roles.push(customRole);
244
+ }
245
+ return roles;
246
+ }
247
+
248
+ resolveGroupRoleNodeId(groupName) {
249
+ const normalized = String(groupName || "").trim().toLowerCase();
250
+ if (!normalized || normalized === "public") {
251
+ return null;
252
+ }
253
+
254
+ const wellKnownRoles = {
255
+ operator: "WellKnownRole_Operator",
256
+ supervisor: "WellKnownRole_Supervisor",
257
+ engineer: "WellKnownRole_Engineer",
258
+ engineering: "WellKnownRole_Engineer",
259
+ observer: "WellKnownRole_Observer",
260
+ admin: "WellKnownRole_ConfigureAdmin",
261
+ configureadmin: "WellKnownRole_ConfigureAdmin",
262
+ securityadmin: "WellKnownRole_SecurityAdmin"
263
+ };
264
+
265
+ if (wellKnownRoles[normalized]) {
266
+ return resolveNodeId(wellKnownRoles[normalized]);
267
+ }
268
+
269
+ return resolveNodeId("ns=1;s=NodeRedRole/" + this.sanitizeRoleSegment(normalized));
270
+ }
271
+
272
+ sanitizeRoleSegment(value) {
273
+ return String(value || "")
274
+ .trim()
275
+ .toLowerCase()
276
+ .replace(/\s+/g, "_")
277
+ .replace(/[^a-z0-9._-]/g, "_");
278
+ }
279
+
280
+ isValidUser(username, password) {
281
+ return this.users.some((user) => {
282
+ if (user.username !== username) {
283
+ return false;
284
+ }
285
+
286
+ if (user.password && user.password === password) {
287
+ return true;
288
+ }
289
+
290
+ if (user.passwordHash) {
291
+ if (!bcrypt) {
292
+ this.node.warn("bcryptjs is not installed, so hashed passwords cannot be validated.");
293
+ return false;
294
+ }
295
+ try {
296
+ return bcrypt.compareSync(password, user.passwordHash);
297
+ } catch (error) {
298
+ this.node.warn("Failed to validate password hash for user " + username + ": " + error.message);
299
+ return false;
300
+ }
301
+ }
302
+
303
+ return false;
304
+ });
305
+ }
306
+
307
+ initializeNamespaces(treeConfig) {
308
+ const addressSpace = this.server.engine.addressSpace;
309
+ const configuredNamespaces = this.buildNamespaceDefinitions(treeConfig);
310
+
311
+ this.namespaces = new Map();
312
+ this.namespaceDefinitions = configuredNamespaces;
313
+
314
+ configuredNamespaces.forEach((uri, namespaceId) => {
315
+ const namespace = addressSpace.getNamespace(uri) || addressSpace.registerNamespace(uri);
316
+ this.namespaces.set(namespaceId, namespace);
317
+ });
318
+
319
+ this.namespace = this.namespaces.get(2);
320
+ }
321
+
322
+ syncNamespaces(treeConfig) {
323
+ const addressSpace = this.server.engine.addressSpace;
324
+ const nextDefinitions = this.buildNamespaceDefinitions(treeConfig);
325
+
326
+ this.namespaceDefinitions.forEach((uri, namespaceId) => {
327
+ const nextUri = nextDefinitions.get(namespaceId);
328
+ if (nextUri && nextUri !== uri) {
329
+ throw new Error("Namespace URI changes require a redeploy: namespace " + namespaceId);
330
+ }
331
+
332
+ if (!nextUri) {
333
+ throw new Error("Removing namespaces requires a redeploy: namespace " + namespaceId);
334
+ }
335
+ });
336
+
337
+ nextDefinitions.forEach((uri, namespaceId) => {
338
+ if (this.namespaces.has(namespaceId)) {
339
+ return;
340
+ }
341
+
342
+ const namespace = addressSpace.getNamespace(uri) || addressSpace.registerNamespace(uri);
343
+ this.namespaces.set(namespaceId, namespace);
344
+ });
345
+
346
+ this.namespaceDefinitions = nextDefinitions;
347
+ this.namespace = this.namespaces.get(2);
348
+ }
349
+
350
+ buildNamespaceDefinitions(treeConfig) {
351
+ const definitions = new Map();
352
+ const configuredNamespaces = Array.isArray(treeConfig && treeConfig.nameSpaces) ? treeConfig.nameSpaces : [];
353
+ let defaultNamespaceUri = this.namespaceUri;
354
+
355
+ configuredNamespaces.forEach((namespaceConfig) => {
356
+ if (namespaceConfig.id === 2) {
357
+ defaultNamespaceUri = namespaceConfig.name;
358
+ }
359
+ });
360
+
361
+ definitions.set(2, defaultNamespaceUri);
362
+
363
+ configuredNamespaces
364
+ .slice()
365
+ .sort((left, right) => left.id - right.id)
366
+ .forEach((namespaceConfig) => {
367
+ definitions.set(namespaceConfig.id, namespaceConfig.name);
368
+ });
369
+
370
+ return definitions;
371
+ }
372
+ }
373
+
374
+ module.exports = {
375
+ OpcUaServerRuntime
376
+ };