node-opcua-alias-name-server 2.176.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/LICENSE +22 -0
- package/README.md +361 -0
- package/dist/add_alias.d.ts +73 -0
- package/dist/add_alias.js +262 -0
- package/dist/add_alias.js.map +1 -0
- package/dist/address_space_alias_store.d.ts +130 -0
- package/dist/address_space_alias_store.js +360 -0
- package/dist/address_space_alias_store.js.map +1 -0
- package/dist/alias_hierarchy.d.ts +45 -0
- package/dist/alias_hierarchy.js +135 -0
- package/dist/alias_hierarchy.js.map +1 -0
- package/dist/alias_index.d.ts +60 -0
- package/dist/alias_index.js +119 -0
- package/dist/alias_index.js.map +1 -0
- package/dist/alias_name_archive.d.ts +45 -0
- package/dist/alias_name_archive.js +75 -0
- package/dist/alias_name_archive.js.map +1 -0
- package/dist/bind_alias_category.d.ts +173 -0
- package/dist/bind_alias_category.js +417 -0
- package/dist/bind_alias_category.js.map +1 -0
- package/dist/bind_configuration_methods.d.ts +44 -0
- package/dist/bind_configuration_methods.js +175 -0
- package/dist/bind_configuration_methods.js.map +1 -0
- package/dist/bind_find_alias.d.ts +61 -0
- package/dist/bind_find_alias.js +227 -0
- package/dist/bind_find_alias.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +64 -0
- package/dist/index.js.map +1 -0
- package/dist/install_alias_names.d.ts +229 -0
- package/dist/install_alias_names.js +146 -0
- package/dist/install_alias_names.js.map +1 -0
- package/dist/last_change.d.ts +87 -0
- package/dist/last_change.js +174 -0
- package/dist/last_change.js.map +1 -0
- package/dist/well_known.d.ts +88 -0
- package/dist/well_known.js +93 -0
- package/dist/well_known.js.map +1 -0
- package/package.json +54 -0
- package/source/add_alias.ts +318 -0
- package/source/address_space_alias_store.ts +417 -0
- package/source/alias_hierarchy.ts +141 -0
- package/source/alias_index.ts +127 -0
- package/source/alias_name_archive.ts +84 -0
- package/source/bind_alias_category.ts +546 -0
- package/source/bind_configuration_methods.ts +219 -0
- package/source/bind_find_alias.ts +290 -0
- package/source/index.ts +74 -0
- package/source/install_alias_names.ts +342 -0
- package/source/last_change.ts +201 -0
- package/source/well_known.ts +101 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module node-opcua-alias-name-server
|
|
4
|
+
*
|
|
5
|
+
* An {@link IAliasStore} backed directly by the address space.
|
|
6
|
+
*
|
|
7
|
+
* This is the default store, and the reason `installAliasNames(server)` needs no
|
|
8
|
+
* application code: a Server whose NodeSet2.xml already models `AliasNameType`
|
|
9
|
+
* instances answers `FindAlias` correctly with nothing else configured. The
|
|
10
|
+
* address space *is* the database.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.AddressSpaceAliasStore = void 0;
|
|
14
|
+
const node_opcua_alias_name_common_1 = require("node-opcua-alias-name-common");
|
|
15
|
+
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
16
|
+
const node_opcua_nodeid_1 = require("node-opcua-nodeid");
|
|
17
|
+
const node_opcua_status_code_1 = require("node-opcua-status-code");
|
|
18
|
+
const add_alias_js_1 = require("./add_alias.js");
|
|
19
|
+
const alias_hierarchy_js_1 = require("./alias_hierarchy.js");
|
|
20
|
+
const well_known_js_1 = require("./well_known.js");
|
|
21
|
+
/**
|
|
22
|
+
* An ExpandedNodeId as a NodeId on this Server, dropping the ServerIndex.
|
|
23
|
+
*
|
|
24
|
+
* Clause 6.3.4 Table 9: *"The ServerIndex in the ExpandedNodeId shall be ignored
|
|
25
|
+
* and the TargetServers Uri shall be used."*
|
|
26
|
+
*
|
|
27
|
+
* Built from the identifier's own parts rather than by re-parsing its string
|
|
28
|
+
* form, which would have to cope with `svr=`, `nsu=` and quoting. When the
|
|
29
|
+
* ExpandedNodeId carries a namespace URI, that URI decides the index — the
|
|
30
|
+
* numeric index travelling beside it belongs to the *sending* Server's namespace
|
|
31
|
+
* table, not ours.
|
|
32
|
+
*/
|
|
33
|
+
function toLocalNodeId(addressSpace, nodeId) {
|
|
34
|
+
let namespaceIndex = nodeId.namespace ?? 0;
|
|
35
|
+
if (nodeId.namespaceUri) {
|
|
36
|
+
const resolved = addressSpace.getNamespaceIndex(nodeId.namespaceUri);
|
|
37
|
+
if (resolved < 0) {
|
|
38
|
+
// a namespace this Server does not know: the Node cannot be here
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
namespaceIndex = resolved;
|
|
42
|
+
}
|
|
43
|
+
return new node_opcua_nodeid_1.NodeId(nodeId.identifierType, nodeId.value, namespaceIndex);
|
|
44
|
+
}
|
|
45
|
+
/** Turn a local NodeId into an ExpandedNodeId with the namespace URI filled in. */
|
|
46
|
+
function toExpandedNodeId(addressSpace, nodeId) {
|
|
47
|
+
const namespaceUri = nodeId.namespace === 0 ? null : addressSpace.getNamespaceUri(nodeId.namespace);
|
|
48
|
+
return new node_opcua_nodeid_1.ExpandedNodeId(nodeId.identifierType, nodeId.value, nodeId.namespace, namespaceUri,
|
|
49
|
+
// clause 7.3: the ServerIndex is carried separately in ServerUris, and
|
|
50
|
+
// clause 6.3.4 Table 9 says an incoming ServerIndex is ignored anyway
|
|
51
|
+
0);
|
|
52
|
+
}
|
|
53
|
+
class AddressSpaceAliasStore {
|
|
54
|
+
addressSpace;
|
|
55
|
+
likeOptions;
|
|
56
|
+
/** Per-category `LastChange`, as a VersionTime (clause 6.3.1). */
|
|
57
|
+
lastChangeByCategory = new Map();
|
|
58
|
+
allowRemoteTargets;
|
|
59
|
+
constructor(addressSpace, options) {
|
|
60
|
+
this.addressSpace = addressSpace;
|
|
61
|
+
this.likeOptions = options?.likeOptions;
|
|
62
|
+
this.allowRemoteTargets = options?.allowRemoteTargets ?? false;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Every alias at or below `query.categoryNodeId` matching the pattern.
|
|
66
|
+
*
|
|
67
|
+
* The search is recursive from the category the Method was called on
|
|
68
|
+
* (clause 6.3.1), so a call on `Aliases` also covers `TagVariables`,
|
|
69
|
+
* `Topics` and anything nested below them.
|
|
70
|
+
*
|
|
71
|
+
* One entry is produced per (AliasName, category) pair: `FindAliasVerbose`
|
|
72
|
+
* has to name the category that actually held the alias, which for a nested
|
|
73
|
+
* hit is the nested one, not the one that was called.
|
|
74
|
+
*/
|
|
75
|
+
async find(query) {
|
|
76
|
+
const root = this.addressSpace.findNode(query.categoryNodeId);
|
|
77
|
+
if (!root || root.nodeClass !== node_opcua_data_model_1.NodeClass.Object) {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
// an invalid pattern throws InvalidLikePatternError, which the Method
|
|
81
|
+
// binding turns into Bad_InvalidArgument (clause 6.3.2 Table 4)
|
|
82
|
+
const pattern = new node_opcua_alias_name_common_1.LikePattern(query.pattern, this.likeOptions);
|
|
83
|
+
const referenceTypeFilter = this.resolveReferenceTypeFilter(query.referenceTypeFilter);
|
|
84
|
+
const entries = [];
|
|
85
|
+
// Stop one past the cap. The caller only needs to know that the cap was
|
|
86
|
+
// exceeded, so collecting the whole hierarchy first would be wasted work
|
|
87
|
+
// -- and on a Server with a large tag set, a `%` pattern would build the
|
|
88
|
+
// entire result set purely to throw it away with Bad_ResponseTooLarge.
|
|
89
|
+
const collectLimit = query.maxResults === undefined ? Number.POSITIVE_INFINITY : query.maxResults + 1;
|
|
90
|
+
for (const category of (0, alias_hierarchy_js_1.collectCategories)(this.addressSpace, root)) {
|
|
91
|
+
if (entries.length >= collectLimit) {
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
// Skipped before its aliases are walked, so the cap is spent only on
|
|
95
|
+
// entries the caller may see - and the scan does less work. Only
|
|
96
|
+
// this category is skipped, not its descendants: the gate is
|
|
97
|
+
// per-category, and a denied parent does not imply a denied child.
|
|
98
|
+
if (query.isVisible && !(await query.isVisible(category.nodeId))) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
for (const alias of (0, alias_hierarchy_js_1.aliasesOf)(this.addressSpace, category)) {
|
|
102
|
+
if (entries.length >= collectLimit) {
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
const aliasName = alias.browseName.name;
|
|
106
|
+
if (!aliasName || !pattern.test(aliasName)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const targets = this.targetsOf(alias, referenceTypeFilter);
|
|
110
|
+
if (targets.length === 0) {
|
|
111
|
+
// clause 6.3.2 Table 3: an alias with no Reference of the
|
|
112
|
+
// requested type is simply not a match
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
entries.push({
|
|
116
|
+
aliasName,
|
|
117
|
+
// the namespace the alias Object was actually published in,
|
|
118
|
+
// not the category's - Aliases and friends live in
|
|
119
|
+
// namespace 0, which clause 6.2 never intends for an alias
|
|
120
|
+
aliasNameNamespaceUri: this.namespaceUriOf(alias.browseName.namespaceIndex),
|
|
121
|
+
referencedNodes: targets.map((t) => t.expandedNodeId),
|
|
122
|
+
// every target is on this Server; aggregating other Servers
|
|
123
|
+
// is out of scope for this package (Annex B / Annex C)
|
|
124
|
+
serverUris: targets.map(() => null),
|
|
125
|
+
categoryNodeId: category.nodeId,
|
|
126
|
+
referenceTypeIds: targets.map((t) => t.referenceTypeId)
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return entries;
|
|
131
|
+
}
|
|
132
|
+
/** `LastChange` for a category, rolled up from its descendants (clause 6.3.1). */
|
|
133
|
+
lastChange(categoryNodeId) {
|
|
134
|
+
const root = this.addressSpace.findNode(categoryNodeId);
|
|
135
|
+
if (!root || root.nodeClass !== node_opcua_data_model_1.NodeClass.Object) {
|
|
136
|
+
return this.lastChangeByCategory.get(categoryNodeId.toString()) ?? 0;
|
|
137
|
+
}
|
|
138
|
+
let latest = 0;
|
|
139
|
+
for (const category of (0, alias_hierarchy_js_1.collectCategories)(this.addressSpace, root)) {
|
|
140
|
+
latest = (0, node_opcua_alias_name_common_1.maxVersionTime)(latest, this.lastChangeByCategory.get(category.nodeId.toString()) ?? 0);
|
|
141
|
+
}
|
|
142
|
+
return latest;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Record that a category changed, at `versionTime` (defaulting to now).
|
|
146
|
+
*
|
|
147
|
+
* Only the category itself is stored; the rollup to ancestors happens on
|
|
148
|
+
* read, so a category that is later re-parented reports correctly without
|
|
149
|
+
* anything having to be recomputed.
|
|
150
|
+
*/
|
|
151
|
+
touch(categoryNodeId, versionTime) {
|
|
152
|
+
const value = versionTime ?? (0, node_opcua_alias_name_common_1.nowVersionTime)();
|
|
153
|
+
const key = categoryNodeId.toString();
|
|
154
|
+
this.lastChangeByCategory.set(key, (0, node_opcua_alias_name_common_1.maxVersionTime)(this.lastChangeByCategory.get(key) ?? 0, value));
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
/** Restore persisted `LastChange` values (clause 6.3.1: "shall be persisted"). */
|
|
158
|
+
restoreLastChange(values) {
|
|
159
|
+
for (const [key, value] of values) {
|
|
160
|
+
this.lastChangeByCategory.set(key, value);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** Snapshot the per-category `LastChange` values for persistence. */
|
|
164
|
+
snapshotLastChange() {
|
|
165
|
+
return [...this.lastChangeByCategory.entries()];
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Add aliases to a category (clause 6.3.4), one StatusCode per entry.
|
|
169
|
+
*
|
|
170
|
+
* The per-item codes of Table 10:
|
|
171
|
+
*
|
|
172
|
+
* - `Bad_NodeIdInvalid` — the NodeId is syntactically unusable.
|
|
173
|
+
* - `Bad_NodeIdUnknown` — the target is on this Server and does not exist.
|
|
174
|
+
* - `Uncertain_ReferenceOutOfServer` — the target is on another Server. The
|
|
175
|
+
* clause is explicit that this is returned **whether or not** a check was
|
|
176
|
+
* performed: *"If the Server does not check for the external Node's
|
|
177
|
+
* existence, it shall return Uncertain_ReferenceOutOfServer."* This Server
|
|
178
|
+
* does not check, because checking means being a Client of the other
|
|
179
|
+
* Server, which is the aggregation these packages exclude by design.
|
|
180
|
+
* - `Bad_NotSupported` — when {@link AddressSpaceAliasStoreOptions.allowRemoteTargets}
|
|
181
|
+
* is off, which Table 10 explicitly permits.
|
|
182
|
+
*
|
|
183
|
+
* An exact duplicate of (AliasName, target, target Server) is `Good` and
|
|
184
|
+
* ignored, whether it was already stored or repeated within this call.
|
|
185
|
+
*/
|
|
186
|
+
add(categoryNodeId, entries) {
|
|
187
|
+
const category = this.addressSpace.findNode(categoryNodeId);
|
|
188
|
+
if (!category || category.nodeClass !== node_opcua_data_model_1.NodeClass.Object) {
|
|
189
|
+
return entries.map(() => node_opcua_status_code_1.StatusCodes.BadNodeIdUnknown);
|
|
190
|
+
}
|
|
191
|
+
const categoryNode = category;
|
|
192
|
+
// duplicates repeated *within* this call are ignored too, so the set
|
|
193
|
+
// has to grow as we go rather than being a snapshot of the start state
|
|
194
|
+
const seenInThisCall = new Set();
|
|
195
|
+
return entries.map((entry) => {
|
|
196
|
+
const target = entry.referencedNodes[0];
|
|
197
|
+
const serverUri = entry.serverUris[0] ?? null;
|
|
198
|
+
if (!target) {
|
|
199
|
+
return node_opcua_status_code_1.StatusCodes.BadNodeIdInvalid;
|
|
200
|
+
}
|
|
201
|
+
if (!entry.aliasName) {
|
|
202
|
+
return node_opcua_status_code_1.StatusCodes.BadNodeIdInvalid;
|
|
203
|
+
}
|
|
204
|
+
const key = `${entry.aliasName}${target.toString()}${serverUri ?? ""}`;
|
|
205
|
+
if (seenInThisCall.has(key)) {
|
|
206
|
+
return node_opcua_status_code_1.StatusCodes.Good;
|
|
207
|
+
}
|
|
208
|
+
seenInThisCall.add(key);
|
|
209
|
+
// Table 9: the ServerIndex inside the ExpandedNodeId is ignored;
|
|
210
|
+
// TargetServers is authoritative
|
|
211
|
+
if (serverUri !== null) {
|
|
212
|
+
if (!this.allowRemoteTargets) {
|
|
213
|
+
return node_opcua_status_code_1.StatusCodes.BadNotSupported;
|
|
214
|
+
}
|
|
215
|
+
return this.addRemote(categoryNode, entry, target, serverUri);
|
|
216
|
+
}
|
|
217
|
+
return this.addLocal(categoryNode, entry, target);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Remove aliases from a category (clause 6.3.5), one StatusCode per entry.
|
|
222
|
+
*
|
|
223
|
+
* `Bad_NotFound` when the name is not in the category, `Bad_InvalidState`
|
|
224
|
+
* when it is there but not owned by this Server — clause 6.3.5 opens by
|
|
225
|
+
* saying a Server "shall only delete AliasName instances that are defined on
|
|
226
|
+
* the Server exposing this Method".
|
|
227
|
+
*
|
|
228
|
+
* An entry with no target removes every target of that name. Removal is
|
|
229
|
+
* all-or-nothing per name: if any target cannot go, none of that name's do.
|
|
230
|
+
*/
|
|
231
|
+
delete(categoryNodeId, entries) {
|
|
232
|
+
const category = this.addressSpace.findNode(categoryNodeId);
|
|
233
|
+
if (!category || category.nodeClass !== node_opcua_data_model_1.NodeClass.Object) {
|
|
234
|
+
return entries.map(() => node_opcua_status_code_1.StatusCodes.BadNotFound);
|
|
235
|
+
}
|
|
236
|
+
const categoryNode = category;
|
|
237
|
+
return entries.map((entry) => {
|
|
238
|
+
const alias = (0, add_alias_js_1.findAlias)(this.addressSpace, categoryNode, entry.aliasName);
|
|
239
|
+
if (!alias) {
|
|
240
|
+
return node_opcua_status_code_1.StatusCodes.BadNotFound;
|
|
241
|
+
}
|
|
242
|
+
// an alias whose targets all live on other Servers was learned from
|
|
243
|
+
// elsewhere and is not ours to delete
|
|
244
|
+
if (this.isForeign(alias)) {
|
|
245
|
+
return node_opcua_status_code_1.StatusCodes.BadInvalidState;
|
|
246
|
+
}
|
|
247
|
+
const requested = entry.referencedNodes ?? [];
|
|
248
|
+
if (requested.length === 0) {
|
|
249
|
+
// "all AliasNames with the provided name are deleted"
|
|
250
|
+
(0, add_alias_js_1.removeAlias)(this.addressSpace, categoryNode, entry.aliasName);
|
|
251
|
+
return node_opcua_status_code_1.StatusCodes.Good;
|
|
252
|
+
}
|
|
253
|
+
// all or nothing: check every requested target is present first
|
|
254
|
+
const references = alias.findReferencesEx(well_known_js_1.ALIAS_FOR, node_opcua_data_model_1.BrowseDirection.Forward);
|
|
255
|
+
const present = new Set(references.map((r) => r.nodeId.toString()));
|
|
256
|
+
const wanted = [];
|
|
257
|
+
for (const target of requested) {
|
|
258
|
+
const local = toLocalNodeId(this.addressSpace, target);
|
|
259
|
+
if (!local || !present.has(local.toString())) {
|
|
260
|
+
return node_opcua_status_code_1.StatusCodes.BadNotFound;
|
|
261
|
+
}
|
|
262
|
+
wanted.push(local);
|
|
263
|
+
}
|
|
264
|
+
for (const target of wanted) {
|
|
265
|
+
(0, add_alias_js_1.removeAlias)(this.addressSpace, categoryNode, entry.aliasName, target);
|
|
266
|
+
}
|
|
267
|
+
return node_opcua_status_code_1.StatusCodes.Good;
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
/** Add an alias whose target is on this Server. */
|
|
271
|
+
addLocal(category, entry, target) {
|
|
272
|
+
const localNodeId = toLocalNodeId(this.addressSpace, target);
|
|
273
|
+
if (!localNodeId) {
|
|
274
|
+
return node_opcua_status_code_1.StatusCodes.BadNodeIdInvalid;
|
|
275
|
+
}
|
|
276
|
+
if (!this.addressSpace.findNode(localNodeId)) {
|
|
277
|
+
// Table 10: "The TargetNode does not exist in the AliasName Server
|
|
278
|
+
// and the TargetServer is the local server"
|
|
279
|
+
return node_opcua_status_code_1.StatusCodes.BadNodeIdUnknown;
|
|
280
|
+
}
|
|
281
|
+
try {
|
|
282
|
+
(0, add_alias_js_1.addAlias)(this.addressSpace, category, entry.aliasName, localNodeId, {
|
|
283
|
+
referenceType: entry.referenceTypeIds[0]
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
// a category restriction (clause 9.3 / 9.4) refused the target
|
|
288
|
+
return node_opcua_status_code_1.StatusCodes.BadNodeIdInvalid;
|
|
289
|
+
}
|
|
290
|
+
return node_opcua_status_code_1.StatusCodes.Good;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Add an alias whose target is on another Server.
|
|
294
|
+
*
|
|
295
|
+
* Always `Uncertain_ReferenceOutOfServer`: this Server does not verify
|
|
296
|
+
* Nodes on other Servers, and clause 6.3.4 says that case returns the
|
|
297
|
+
* uncertain code rather than success.
|
|
298
|
+
*/
|
|
299
|
+
addRemote(category, entry, target, _serverUri) {
|
|
300
|
+
try {
|
|
301
|
+
(0, add_alias_js_1.addAlias)(this.addressSpace, category, entry.aliasName, target, {
|
|
302
|
+
referenceType: entry.referenceTypeIds[0],
|
|
303
|
+
allowUnresolvedTarget: true
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
return node_opcua_status_code_1.StatusCodes.BadNodeIdInvalid;
|
|
308
|
+
}
|
|
309
|
+
return node_opcua_status_code_1.StatusCodes.UncertainReferenceOutOfServer;
|
|
310
|
+
}
|
|
311
|
+
/** True when none of the alias's targets are on this Server. */
|
|
312
|
+
isForeign(alias) {
|
|
313
|
+
const references = alias.findReferencesEx(well_known_js_1.ALIAS_FOR, node_opcua_data_model_1.BrowseDirection.Forward);
|
|
314
|
+
if (references.length === 0) {
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
return references.every((reference) => this.addressSpace.findNode(reference.nodeId) === null);
|
|
318
|
+
}
|
|
319
|
+
/** The URI of a namespace index, or undefined for namespace 0. */
|
|
320
|
+
namespaceUriOf(namespaceIndex) {
|
|
321
|
+
// namespace 0 is the OPC Foundation's and is never a legitimate alias
|
|
322
|
+
// namespace; reporting it would be worse than reporting nothing
|
|
323
|
+
return namespaceIndex === 0 ? undefined : this.addressSpace.getNamespaceUri(namespaceIndex);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Resolve the `ReferenceTypeFilter` argument.
|
|
327
|
+
*
|
|
328
|
+
* A null or absent NodeId means any ReferenceType (clause 6.3.2 Table 3).
|
|
329
|
+
*/
|
|
330
|
+
resolveReferenceTypeFilter(filter) {
|
|
331
|
+
if (!filter || filter.isEmpty()) {
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
return filter;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* The Nodes an alias points at.
|
|
338
|
+
*
|
|
339
|
+
* `findReferencesEx` already includes subtypes of the ReferenceType, which
|
|
340
|
+
* is what clause 6.3.2 Table 3 asks for: "Any ReferenceType includes all
|
|
341
|
+
* subtypes of that ReferenceType".
|
|
342
|
+
*
|
|
343
|
+
* An absent filter falls back to `AliasFor` rather than to *every*
|
|
344
|
+
* ReferenceType. Table 3 describes the filter as "AliasFor or one of its
|
|
345
|
+
* subtypes", and clause 8.2 makes `AliasFor` the ReferenceType that links an
|
|
346
|
+
* AliasName to what it names; taking "any" literally would return the
|
|
347
|
+
* alias's `HasTypeDefinition` target and its Organizes back-reference, which
|
|
348
|
+
* are not things the alias names.
|
|
349
|
+
*/
|
|
350
|
+
targetsOf(alias, referenceTypeFilter) {
|
|
351
|
+
const referenceType = referenceTypeFilter ?? well_known_js_1.ALIAS_FOR;
|
|
352
|
+
const references = alias.findReferencesEx(referenceType, node_opcua_data_model_1.BrowseDirection.Forward);
|
|
353
|
+
return references.map((reference) => ({
|
|
354
|
+
expandedNodeId: toExpandedNodeId(this.addressSpace, reference.nodeId),
|
|
355
|
+
referenceTypeId: reference.referenceType
|
|
356
|
+
}));
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
exports.AddressSpaceAliasStore = AddressSpaceAliasStore;
|
|
360
|
+
//# sourceMappingURL=address_space_alias_store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address_space_alias_store.js","sourceRoot":"","sources":["../source/address_space_alias_store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module node-opcua-alias-name-server
|
|
3
|
+
*
|
|
4
|
+
* Walking the AliasName hierarchy in the address space (OPC 10000-17
|
|
5
|
+
* clause 6.3.1).
|
|
6
|
+
*/
|
|
7
|
+
import type { BaseNode, IAddressSpace, UAObject, UAObjectType } from "node-opcua-address-space-base";
|
|
8
|
+
import type { NodeId } from "node-opcua-nodeid";
|
|
9
|
+
/** Resolve `AliasNameCategoryType`, or null on an address space without Part 17. */
|
|
10
|
+
export declare function findAliasNameCategoryType(addressSpace: IAddressSpace): UAObjectType | null;
|
|
11
|
+
/** Resolve `AliasNameType`, or null on an address space without Part 17. */
|
|
12
|
+
export declare function findAliasNameType(addressSpace: IAddressSpace): UAObjectType | null;
|
|
13
|
+
/** True when `node` is an instance of `AliasNameCategoryType` (or a subtype). */
|
|
14
|
+
export declare function isAliasNameCategory(addressSpace: IAddressSpace, node: BaseNode): boolean;
|
|
15
|
+
/** True when `node` is an instance of `AliasNameType` (or a subtype). */
|
|
16
|
+
export declare function isAliasName(addressSpace: IAddressSpace, node: BaseNode): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Every `AliasNameCategoryType` instance at or below `root`, depth first.
|
|
19
|
+
*
|
|
20
|
+
* A category may legitimately be reached more than once — clause 6.3.1 allows an
|
|
21
|
+
* `<Alias>` (and by extension a subtree) to appear in more than one place — so
|
|
22
|
+
* `seen` both de-duplicates and makes a cyclic hierarchy terminate rather than
|
|
23
|
+
* hang the Method call.
|
|
24
|
+
*/
|
|
25
|
+
export declare function collectCategories(addressSpace: IAddressSpace, root: UAObject): UAObject[];
|
|
26
|
+
/** The `AliasNameType` instances Organized directly by `category`. */
|
|
27
|
+
export declare function aliasesOf(addressSpace: IAddressSpace, category: UAObject): UAObject[];
|
|
28
|
+
/**
|
|
29
|
+
* Every `AliasNameCategoryType` instance reachable from `Aliases`, plus any
|
|
30
|
+
* roots named explicitly.
|
|
31
|
+
*
|
|
32
|
+
* Discovery walks the hierarchy below `Aliases` rather than sweeping the whole
|
|
33
|
+
* address space, because that is where clause 9.1 puts categories: vendors "are
|
|
34
|
+
* free to add additional instances of AliasNameCategoryType under this
|
|
35
|
+
* hierarchy". There is also no way to sweep — the address space keeps no inverse
|
|
36
|
+
* `HasTypeDefinition` reference from an ObjectType to its instances, so a type
|
|
37
|
+
* cannot be asked for them.
|
|
38
|
+
*
|
|
39
|
+
* `additionalRoots` is the escape hatch for a Server that models a category
|
|
40
|
+
* somewhere else: without it that category's MANDATORY `FindAlias` would stay
|
|
41
|
+
* unbound, which is the very defect this package exists to fix.
|
|
42
|
+
*/
|
|
43
|
+
export declare function collectAllCategories(addressSpace: IAddressSpace, additionalRoots?: Array<NodeId | UAObject>): UAObject[];
|
|
44
|
+
/** The NodeIds of the well-known categories present in this address space. */
|
|
45
|
+
export declare function presentWellKnownCategories(addressSpace: IAddressSpace): NodeId[];
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module node-opcua-alias-name-server
|
|
4
|
+
*
|
|
5
|
+
* Walking the AliasName hierarchy in the address space (OPC 10000-17
|
|
6
|
+
* clause 6.3.1).
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.findAliasNameCategoryType = findAliasNameCategoryType;
|
|
10
|
+
exports.findAliasNameType = findAliasNameType;
|
|
11
|
+
exports.isAliasNameCategory = isAliasNameCategory;
|
|
12
|
+
exports.isAliasName = isAliasName;
|
|
13
|
+
exports.collectCategories = collectCategories;
|
|
14
|
+
exports.aliasesOf = aliasesOf;
|
|
15
|
+
exports.collectAllCategories = collectAllCategories;
|
|
16
|
+
exports.presentWellKnownCategories = presentWellKnownCategories;
|
|
17
|
+
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
18
|
+
const well_known_js_1 = require("./well_known.js");
|
|
19
|
+
/** True when `node` is an Object whose TypeDefinition is `type` or a subtype. */
|
|
20
|
+
function isInstanceOf(node, type) {
|
|
21
|
+
if (!type || node.nodeClass !== node_opcua_data_model_1.NodeClass.Object) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const typeDefinition = node.typeDefinitionObj;
|
|
25
|
+
if (!typeDefinition) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
return typeDefinition.nodeId.value === type.nodeId.value || typeDefinition.isSubtypeOf(type);
|
|
29
|
+
}
|
|
30
|
+
/** Resolve `AliasNameCategoryType`, or null on an address space without Part 17. */
|
|
31
|
+
function findAliasNameCategoryType(addressSpace) {
|
|
32
|
+
return addressSpace.findObjectType(well_known_js_1.ALIAS_NAME_CATEGORY_TYPE);
|
|
33
|
+
}
|
|
34
|
+
/** Resolve `AliasNameType`, or null on an address space without Part 17. */
|
|
35
|
+
function findAliasNameType(addressSpace) {
|
|
36
|
+
return addressSpace.findObjectType(well_known_js_1.ALIAS_NAME_TYPE);
|
|
37
|
+
}
|
|
38
|
+
/** True when `node` is an instance of `AliasNameCategoryType` (or a subtype). */
|
|
39
|
+
function isAliasNameCategory(addressSpace, node) {
|
|
40
|
+
return isInstanceOf(node, findAliasNameCategoryType(addressSpace));
|
|
41
|
+
}
|
|
42
|
+
/** True when `node` is an instance of `AliasNameType` (or a subtype). */
|
|
43
|
+
function isAliasName(addressSpace, node) {
|
|
44
|
+
return isInstanceOf(node, findAliasNameType(addressSpace));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The Organized children of a category.
|
|
48
|
+
*
|
|
49
|
+
* `findReferencesExAsObject` follows subtypes of the ReferenceType, so a vendor
|
|
50
|
+
* subtype of `Organizes` is included, and `HierarchicalReferences` is used as
|
|
51
|
+
* the base so a Server that nests categories with `HasComponent` is not missed.
|
|
52
|
+
*/
|
|
53
|
+
function organizedChildren(category) {
|
|
54
|
+
return category.findReferencesExAsObject("HierarchicalReferences", node_opcua_data_model_1.BrowseDirection.Forward);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Every `AliasNameCategoryType` instance at or below `root`, depth first.
|
|
58
|
+
*
|
|
59
|
+
* A category may legitimately be reached more than once — clause 6.3.1 allows an
|
|
60
|
+
* `<Alias>` (and by extension a subtree) to appear in more than one place — so
|
|
61
|
+
* `seen` both de-duplicates and makes a cyclic hierarchy terminate rather than
|
|
62
|
+
* hang the Method call.
|
|
63
|
+
*/
|
|
64
|
+
function collectCategories(addressSpace, root) {
|
|
65
|
+
const result = [];
|
|
66
|
+
const seen = new Set();
|
|
67
|
+
const visit = (category) => {
|
|
68
|
+
const key = category.nodeId.toString();
|
|
69
|
+
if (seen.has(key)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
seen.add(key);
|
|
73
|
+
result.push(category);
|
|
74
|
+
for (const child of organizedChildren(category)) {
|
|
75
|
+
if (isAliasNameCategory(addressSpace, child)) {
|
|
76
|
+
visit(child);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
visit(root);
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
/** The `AliasNameType` instances Organized directly by `category`. */
|
|
84
|
+
function aliasesOf(addressSpace, category) {
|
|
85
|
+
const result = [];
|
|
86
|
+
for (const child of organizedChildren(category)) {
|
|
87
|
+
if (isAliasName(addressSpace, child)) {
|
|
88
|
+
result.push(child);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Every `AliasNameCategoryType` instance reachable from `Aliases`, plus any
|
|
95
|
+
* roots named explicitly.
|
|
96
|
+
*
|
|
97
|
+
* Discovery walks the hierarchy below `Aliases` rather than sweeping the whole
|
|
98
|
+
* address space, because that is where clause 9.1 puts categories: vendors "are
|
|
99
|
+
* free to add additional instances of AliasNameCategoryType under this
|
|
100
|
+
* hierarchy". There is also no way to sweep — the address space keeps no inverse
|
|
101
|
+
* `HasTypeDefinition` reference from an ObjectType to its instances, so a type
|
|
102
|
+
* cannot be asked for them.
|
|
103
|
+
*
|
|
104
|
+
* `additionalRoots` is the escape hatch for a Server that models a category
|
|
105
|
+
* somewhere else: without it that category's MANDATORY `FindAlias` would stay
|
|
106
|
+
* unbound, which is the very defect this package exists to fix.
|
|
107
|
+
*/
|
|
108
|
+
function collectAllCategories(addressSpace, additionalRoots) {
|
|
109
|
+
const byId = new Map();
|
|
110
|
+
const roots = [];
|
|
111
|
+
const aliasesRoot = addressSpace.findNode(well_known_js_1.WellKnownCategories.Aliases);
|
|
112
|
+
if (aliasesRoot) {
|
|
113
|
+
roots.push(aliasesRoot);
|
|
114
|
+
}
|
|
115
|
+
for (const extra of additionalRoots ?? []) {
|
|
116
|
+
const node = "nodeClass" in extra ? extra : addressSpace.findNode(extra);
|
|
117
|
+
if (node) {
|
|
118
|
+
roots.push(node);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
for (const root of roots) {
|
|
122
|
+
if (root.nodeClass !== node_opcua_data_model_1.NodeClass.Object) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
for (const category of collectCategories(addressSpace, root)) {
|
|
126
|
+
byId.set(category.nodeId.toString(), category);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return [...byId.values()];
|
|
130
|
+
}
|
|
131
|
+
/** The NodeIds of the well-known categories present in this address space. */
|
|
132
|
+
function presentWellKnownCategories(addressSpace) {
|
|
133
|
+
return Object.values(well_known_js_1.WellKnownCategories).filter((nodeId) => addressSpace.findNode(nodeId) !== null);
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=alias_hierarchy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alias_hierarchy.js","sourceRoot":"","sources":["../source/alias_hierarchy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module node-opcua-alias-name-server
|
|
3
|
+
*
|
|
4
|
+
* A per-category index from AliasName to the `AliasNameType` Object that carries
|
|
5
|
+
* it.
|
|
6
|
+
*
|
|
7
|
+
* ## Why this exists
|
|
8
|
+
*
|
|
9
|
+
* Looking an alias up by name means finding a child of the category with a given
|
|
10
|
+
* BrowseName. The address space has an O(1) index for exactly that — but
|
|
11
|
+
* `getChildByName` only consults it for `HasChild` subtypes, and an alias is an
|
|
12
|
+
* `Organizes` child of its category (clause 6.3 Table 2). `getFolderElementByName`
|
|
13
|
+
* does cover `Organizes`, but scans. So neither route is both correct and fast.
|
|
14
|
+
*
|
|
15
|
+
* That matters because `addAlias` has to look for an existing alias of the same
|
|
16
|
+
* name before creating one, so a Server building N aliases performed N linear
|
|
17
|
+
* scans of a growing category — quadratic. Measured on a category holding 1500
|
|
18
|
+
* aliases, 200 lookups cost 97 ms by scanning and 0 ms through this index, and
|
|
19
|
+
* building 1500 aliases went from 2545 ms to 1686 ms.
|
|
20
|
+
*
|
|
21
|
+
* That is not the whole story: the larger remaining cost is inside
|
|
22
|
+
* `UAObjectType.instantiate`, which is itself superlinear in the number of
|
|
23
|
+
* children the parent already has. That is an address-space concern rather than
|
|
24
|
+
* an AliasName one, and is tracked separately.
|
|
25
|
+
*
|
|
26
|
+
* ## How it stays correct
|
|
27
|
+
*
|
|
28
|
+
* The index is built lazily, from one full scan, so aliases modelled in a
|
|
29
|
+
* NodeSet2.xml are picked up. After that it is maintained incrementally by
|
|
30
|
+
* {@link noteAliasAdded} and {@link noteAliasRemoved}, which `addAlias` and
|
|
31
|
+
* `removeAlias` call.
|
|
32
|
+
*
|
|
33
|
+
* A hit is verified against the address space before being returned, so an alias
|
|
34
|
+
* deleted by other means degrades to a miss rather than a dangling Object. A
|
|
35
|
+
* miss is trusted: an alias created behind this package's back after the index
|
|
36
|
+
* was built would not be found, and `addAlias` would then fail loudly on the
|
|
37
|
+
* duplicate BrowseName rather than corrupting anything. Call
|
|
38
|
+
* {@link invalidateAliasIndex} if a Server mutates a category by other means.
|
|
39
|
+
*
|
|
40
|
+
* Keyed by the node itself in a `WeakMap`, so a disposed address space takes its
|
|
41
|
+
* indexes with it.
|
|
42
|
+
*/
|
|
43
|
+
import type { IAddressSpace, UAObject } from "node-opcua-address-space-base";
|
|
44
|
+
import type { NodeId } from "node-opcua-nodeid";
|
|
45
|
+
/**
|
|
46
|
+
* The `AliasNameType` instance with this name in `category`, or null.
|
|
47
|
+
*
|
|
48
|
+
* O(1) after the first call on a given category.
|
|
49
|
+
*/
|
|
50
|
+
export declare function lookupAlias(addressSpace: IAddressSpace, category: UAObject, aliasName: string): UAObject | null;
|
|
51
|
+
/** Record a newly created alias. */
|
|
52
|
+
export declare function noteAliasAdded(addressSpace: IAddressSpace, category: UAObject, aliasName: string, nodeId: NodeId): void;
|
|
53
|
+
/** Record a removed alias. */
|
|
54
|
+
export declare function noteAliasRemoved(addressSpace: IAddressSpace, category: UAObject, aliasName: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Forget a category's index, so it is rebuilt from the address space on next
|
|
57
|
+
* use. Needed only if a Server adds or removes aliases without going through
|
|
58
|
+
* {@link addAlias} / {@link removeAlias}.
|
|
59
|
+
*/
|
|
60
|
+
export declare function invalidateAliasIndex(category: UAObject): void;
|