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.
Files changed (51) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +361 -0
  3. package/dist/add_alias.d.ts +73 -0
  4. package/dist/add_alias.js +262 -0
  5. package/dist/add_alias.js.map +1 -0
  6. package/dist/address_space_alias_store.d.ts +130 -0
  7. package/dist/address_space_alias_store.js +360 -0
  8. package/dist/address_space_alias_store.js.map +1 -0
  9. package/dist/alias_hierarchy.d.ts +45 -0
  10. package/dist/alias_hierarchy.js +135 -0
  11. package/dist/alias_hierarchy.js.map +1 -0
  12. package/dist/alias_index.d.ts +60 -0
  13. package/dist/alias_index.js +119 -0
  14. package/dist/alias_index.js.map +1 -0
  15. package/dist/alias_name_archive.d.ts +45 -0
  16. package/dist/alias_name_archive.js +75 -0
  17. package/dist/alias_name_archive.js.map +1 -0
  18. package/dist/bind_alias_category.d.ts +173 -0
  19. package/dist/bind_alias_category.js +417 -0
  20. package/dist/bind_alias_category.js.map +1 -0
  21. package/dist/bind_configuration_methods.d.ts +44 -0
  22. package/dist/bind_configuration_methods.js +175 -0
  23. package/dist/bind_configuration_methods.js.map +1 -0
  24. package/dist/bind_find_alias.d.ts +61 -0
  25. package/dist/bind_find_alias.js +227 -0
  26. package/dist/bind_find_alias.js.map +1 -0
  27. package/dist/index.d.ts +18 -0
  28. package/dist/index.js +64 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/install_alias_names.d.ts +229 -0
  31. package/dist/install_alias_names.js +146 -0
  32. package/dist/install_alias_names.js.map +1 -0
  33. package/dist/last_change.d.ts +87 -0
  34. package/dist/last_change.js +174 -0
  35. package/dist/last_change.js.map +1 -0
  36. package/dist/well_known.d.ts +88 -0
  37. package/dist/well_known.js +93 -0
  38. package/dist/well_known.js.map +1 -0
  39. package/package.json +54 -0
  40. package/source/add_alias.ts +318 -0
  41. package/source/address_space_alias_store.ts +417 -0
  42. package/source/alias_hierarchy.ts +141 -0
  43. package/source/alias_index.ts +127 -0
  44. package/source/alias_name_archive.ts +84 -0
  45. package/source/bind_alias_category.ts +546 -0
  46. package/source/bind_configuration_methods.ts +219 -0
  47. package/source/bind_find_alias.ts +290 -0
  48. package/source/index.ts +74 -0
  49. package/source/install_alias_names.ts +342 -0
  50. package/source/last_change.ts +201 -0
  51. package/source/well_known.ts +101 -0
@@ -0,0 +1,262 @@
1
+ "use strict";
2
+ /**
3
+ * @module node-opcua-alias-name-server
4
+ *
5
+ * Creating and removing `AliasNameType` instances from code, for Servers whose
6
+ * address space is built programmatically rather than loaded from a NodeSet2.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AliasNameError = void 0;
10
+ exports.addAlias = addAlias;
11
+ exports.removeAlias = removeAlias;
12
+ exports.findAlias = findAlias;
13
+ const node_opcua_data_model_1 = require("node-opcua-data-model");
14
+ const node_opcua_nodeid_1 = require("node-opcua-nodeid");
15
+ const alias_hierarchy_js_1 = require("./alias_hierarchy.js");
16
+ const alias_index_js_1 = require("./alias_index.js");
17
+ const bind_alias_category_js_1 = require("./bind_alias_category.js");
18
+ const well_known_js_1 = require("./well_known.js");
19
+ /** Raised when an alias would break a rule of OPC 10000-17. */
20
+ class AliasNameError extends Error {
21
+ constructor(message) {
22
+ super(message);
23
+ this.name = "AliasNameError";
24
+ }
25
+ }
26
+ exports.AliasNameError = AliasNameError;
27
+ /**
28
+ * Add an `AliasNameType` instance under `category`, naming `target`.
29
+ *
30
+ * Enforces clause 6.2:
31
+ *
32
+ * - the string part of the BrowseName equals the DisplayName, with an empty
33
+ * locale and no other locale;
34
+ * - the Object has at least one `AliasFor` Reference;
35
+ * - the BrowseName is immutable once created. There is deliberately no rename:
36
+ * "If an AliasName is to be changed, it shall be a deletion of the old
37
+ * AliasName and the addition of the new AliasName", which yields a new NodeId
38
+ * and is what lets an aggregating Server notice the change.
39
+ *
40
+ * and the category restrictions of clauses 9.3 and 9.4, where the target is
41
+ * local and therefore checkable.
42
+ *
43
+ * Adding the same (name, target) twice returns the existing node rather than
44
+ * creating a duplicate.
45
+ */
46
+ function addAlias(addressSpace, category, aliasName, target, options) {
47
+ const categoryNode = coerceCategory(addressSpace, category);
48
+ const referenceTypeId = coerceReferenceType(addressSpace, options?.referenceType);
49
+ if (!aliasName) {
50
+ throw new AliasNameError("addAlias: the alias name must not be empty");
51
+ }
52
+ // A target on another Server is not in this address space, so it can be
53
+ // neither resolved nor checked against the category restrictions.
54
+ let targetNodeId;
55
+ if (options?.allowUnresolvedTarget) {
56
+ targetNodeId = target instanceof node_opcua_nodeid_1.NodeId ? target : target.nodeId;
57
+ }
58
+ else {
59
+ const targetNode = coerceTarget(addressSpace, target);
60
+ targetNodeId = targetNode.nodeId;
61
+ assertTargetAllowedInCategory(addressSpace, categoryNode, targetNode);
62
+ }
63
+ const existing = findAlias(addressSpace, categoryNode, aliasName);
64
+ if (existing) {
65
+ // clause 6.3.1: multiple <Alias> instances may point at the same Node,
66
+ // and the same name may name several Nodes; adding a target that is
67
+ // already there is a no-op rather than an error
68
+ const alreadyLinked = existing
69
+ .findReferencesEx(well_known_js_1.ALIAS_FOR, node_opcua_data_model_1.BrowseDirection.Forward)
70
+ .some((reference) => reference.nodeId.toString() === targetNodeId.toString());
71
+ if (!alreadyLinked) {
72
+ existing.addReference({ referenceType: referenceTypeId, nodeId: targetNodeId });
73
+ // clause 6.3.1: "the referenced Nodes of an AliasName in the
74
+ // AliasNameCategory changed"
75
+ notifyAliasChanged(addressSpace, categoryNode.nodeId);
76
+ }
77
+ return existing;
78
+ }
79
+ const aliasNameType = (0, alias_hierarchy_js_1.findAliasNameType)(addressSpace);
80
+ if (!aliasNameType) {
81
+ throw new AliasNameError("addAlias: AliasNameType (i=23455) is not in the address space");
82
+ }
83
+ const namespace = addressSpace.getNamespace(options?.namespaceIndex ?? addressSpace.getOwnNamespace().index);
84
+ const alias = aliasNameType.instantiate({
85
+ browseName: { name: aliasName, namespaceIndex: namespace.index },
86
+ // clause 6.2: the DisplayName is the string part of the BrowseName, with
87
+ // an empty locale and no other locale - hence a single LocalizedText
88
+ // carrying a null locale, not a list
89
+ displayName: { locale: null, text: aliasName },
90
+ organizedBy: categoryNode,
91
+ namespace
92
+ });
93
+ alias.addReference({ referenceType: referenceTypeId, nodeId: targetNodeId });
94
+ (0, alias_index_js_1.noteAliasAdded)(addressSpace, categoryNode, aliasName, alias.nodeId);
95
+ // clause 6.3.1: "an AliasName was added to [...] the AliasNameCategory"
96
+ notifyAliasChanged(addressSpace, categoryNode.nodeId);
97
+ return alias;
98
+ }
99
+ /**
100
+ * Remove one target from an alias, or the whole alias when no target is given.
101
+ *
102
+ * Removing the last target deletes the `AliasNameType` node: clause 7.2 says the
103
+ * ReferencedNodes array always has at least one entry, so an alias naming
104
+ * nothing cannot be represented.
105
+ *
106
+ * @returns true when something was removed.
107
+ */
108
+ function removeAlias(addressSpace, category, aliasName, target) {
109
+ const categoryNode = coerceCategory(addressSpace, category);
110
+ const alias = findAlias(addressSpace, categoryNode, aliasName);
111
+ if (!alias) {
112
+ return false;
113
+ }
114
+ if (!target) {
115
+ addressSpace.deleteNode(alias.nodeId);
116
+ (0, alias_index_js_1.noteAliasRemoved)(addressSpace, categoryNode, aliasName);
117
+ notifyAliasChanged(addressSpace, categoryNode.nodeId);
118
+ return true;
119
+ }
120
+ const targetNodeId = target instanceof node_opcua_nodeid_1.NodeId ? target : target.nodeId;
121
+ const references = alias.findReferencesEx(well_known_js_1.ALIAS_FOR, node_opcua_data_model_1.BrowseDirection.Forward);
122
+ const match = references.find((reference) => reference.nodeId.toString() === targetNodeId.toString());
123
+ if (!match) {
124
+ return false;
125
+ }
126
+ if (references.length === 1) {
127
+ // the last target: the alias itself goes (clause 7.2)
128
+ addressSpace.deleteNode(alias.nodeId);
129
+ (0, alias_index_js_1.noteAliasRemoved)(addressSpace, categoryNode, aliasName);
130
+ notifyAliasChanged(addressSpace, categoryNode.nodeId);
131
+ return true;
132
+ }
133
+ alias.removeReference({ referenceType: match.referenceType, nodeId: targetNodeId });
134
+ notifyAliasChanged(addressSpace, categoryNode.nodeId);
135
+ return true;
136
+ }
137
+ /**
138
+ * The `AliasNameType` instance with this name Organized by `category`, if any.
139
+ *
140
+ * Compares the string part only, ignoring the namespace, as clause 6.2 requires.
141
+ * Backed by a per-category index — see {@link lookupAlias} for why a plain scan
142
+ * was not good enough.
143
+ */
144
+ function findAlias(addressSpace, category, aliasName) {
145
+ return (0, alias_index_js_1.lookupAlias)(addressSpace, category, aliasName);
146
+ }
147
+ /**
148
+ * Enforce the target restrictions of clauses 9.3 and 9.4.
149
+ *
150
+ * `TagVariables` restricts targets to Variables; `Topics` restricts them to
151
+ * `PublishedDataSetType` instances or subtypes. Both are checked only where the
152
+ * target is local — a Node on another Server cannot be inspected, which is the
153
+ * same reason clause 6.3.4 has `Uncertain_ReferenceOutOfServer`.
154
+ *
155
+ * The restriction applies to the whole subtree: an alias nested three levels
156
+ * below `TagVariables` is still "in the TagVariables hierarchy" (clause 9.3).
157
+ */
158
+ function assertTargetAllowedInCategory(addressSpace, category, target) {
159
+ if (isWithin(addressSpace, category, well_known_js_1.WellKnownCategories.TagVariables)) {
160
+ if (target.nodeClass !== node_opcua_data_model_1.NodeClass.Variable) {
161
+ throw new AliasNameError(`addAlias: TagVariables restricts targets to Variables (OPC 10000-17 clause 9.3); ` +
162
+ `${target.browseName.toString()} is a ${node_opcua_data_model_1.NodeClass[target.nodeClass]}`);
163
+ }
164
+ }
165
+ if (isWithin(addressSpace, category, well_known_js_1.WellKnownCategories.Topics)) {
166
+ const publishedDataSetType = addressSpace.findObjectType(well_known_js_1.PUBLISHED_DATA_SET_TYPE);
167
+ const typeDefinition = target.nodeClass === node_opcua_data_model_1.NodeClass.Object ? target.typeDefinitionObj : null;
168
+ const ok = publishedDataSetType &&
169
+ typeDefinition &&
170
+ (typeDefinition.nodeId.value === publishedDataSetType.nodeId.value || typeDefinition.isSubtypeOf(publishedDataSetType));
171
+ if (!ok) {
172
+ throw new AliasNameError(`addAlias: Topics restricts targets to PublishedDataSetType or a subtype ` +
173
+ `(OPC 10000-17 clause 9.4); ${target.browseName.toString()} is not one`);
174
+ }
175
+ }
176
+ }
177
+ /** True when `category` is `ancestorNodeId` or nested anywhere below it. */
178
+ function isWithin(addressSpace, category, ancestorNodeId) {
179
+ const ancestor = addressSpace.findNode(ancestorNodeId);
180
+ if (!ancestor) {
181
+ return false;
182
+ }
183
+ const seen = new Set();
184
+ const walkUp = (node) => {
185
+ const key = node.nodeId.toString();
186
+ if (seen.has(key)) {
187
+ return false;
188
+ }
189
+ seen.add(key);
190
+ if (key === ancestor.nodeId.toString()) {
191
+ return true;
192
+ }
193
+ for (const parent of node.findReferencesExAsObject("HierarchicalReferences", node_opcua_data_model_1.BrowseDirection.Inverse)) {
194
+ if (walkUp(parent)) {
195
+ return true;
196
+ }
197
+ }
198
+ return false;
199
+ };
200
+ return walkUp(category);
201
+ }
202
+ /** Accept either a category node or its NodeId. */
203
+ function coerceCategory(addressSpace, category) {
204
+ if (!(category instanceof node_opcua_nodeid_1.NodeId)) {
205
+ return category;
206
+ }
207
+ const node = addressSpace.findNode(category);
208
+ if (!node || node.nodeClass !== node_opcua_data_model_1.NodeClass.Object) {
209
+ throw new AliasNameError(`addAlias: ${category.toString()} is not an Object in this address space`);
210
+ }
211
+ const typeDefinition = node.typeDefinitionObj;
212
+ const categoryType = addressSpace.findObjectType(well_known_js_1.ALIAS_NAME_CATEGORY_TYPE);
213
+ if (categoryType &&
214
+ typeDefinition &&
215
+ typeDefinition.nodeId.value !== categoryType.nodeId.value &&
216
+ !typeDefinition.isSubtypeOf(categoryType)) {
217
+ throw new AliasNameError(`addAlias: ${category.toString()} is not an AliasNameCategoryType instance`);
218
+ }
219
+ return node;
220
+ }
221
+ /** Accept either a target node or its NodeId. */
222
+ function coerceTarget(addressSpace, target) {
223
+ if (!(target instanceof node_opcua_nodeid_1.NodeId)) {
224
+ return target;
225
+ }
226
+ const node = addressSpace.findNode(target);
227
+ if (!node) {
228
+ throw new AliasNameError(`addAlias: target ${target.toString()} does not exist in this address space`);
229
+ }
230
+ return node;
231
+ }
232
+ /** Resolve the ReferenceType, defaulting to `AliasFor` (clause 8.2). */
233
+ function coerceReferenceType(addressSpace, referenceType) {
234
+ if (!referenceType) {
235
+ return well_known_js_1.ALIAS_FOR;
236
+ }
237
+ const resolved = typeof referenceType === "string" ? addressSpace.findReferenceType(referenceType)?.nodeId : referenceType;
238
+ if (!resolved) {
239
+ throw new AliasNameError(`addAlias: unknown ReferenceType ${String(referenceType)}`);
240
+ }
241
+ const aliasFor = addressSpace.findReferenceType(well_known_js_1.ALIAS_FOR);
242
+ const candidate = addressSpace.findReferenceType(resolved);
243
+ if (aliasFor && candidate && candidate.nodeId.value !== aliasFor.nodeId.value && !candidate.isSubtypeOf(aliasFor)) {
244
+ throw new AliasNameError(`addAlias: ${candidate.browseName.toString()} is not AliasFor or a subtype of it (OPC 10000-17 clause 8.2)`);
245
+ }
246
+ return resolved;
247
+ }
248
+ /**
249
+ * Tell the installed `LastChange` tracker that a category changed
250
+ * (clause 6.3.1).
251
+ *
252
+ * Routed through whatever installation recorded on the address space rather
253
+ * than through a parameter, so `addAlias` keeps its simple signature and a
254
+ * Server that has not installed AliasNames is unaffected. Fire and forget: the
255
+ * Property is written synchronously, only the persistence write is async, and
256
+ * failing to persist must not fail the caller's add.
257
+ */
258
+ function notifyAliasChanged(addressSpace, categoryNodeId) {
259
+ const installed = (0, bind_alias_category_js_1.getInstalledAliasNames)(addressSpace);
260
+ void installed?.lastChange?.touch(categoryNodeId);
261
+ }
262
+ //# sourceMappingURL=add_alias.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add_alias.js","sourceRoot":"","sources":["../source/add_alias.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * @module node-opcua-alias-name-server
3
+ *
4
+ * An {@link IAliasStore} backed directly by the address space.
5
+ *
6
+ * This is the default store, and the reason `installAliasNames(server)` needs no
7
+ * application code: a Server whose NodeSet2.xml already models `AliasNameType`
8
+ * instances answers `FindAlias` correctly with nothing else configured. The
9
+ * address space *is* the database.
10
+ */
11
+ import type { IAddressSpace } from "node-opcua-address-space-base";
12
+ import { type AliasEntry, type AliasQuery, type IAliasStore, type LikeOptions } from "node-opcua-alias-name-common";
13
+ import { type NodeId } from "node-opcua-nodeid";
14
+ import { type StatusCode } from "node-opcua-status-code";
15
+ export interface AddressSpaceAliasStoreOptions {
16
+ /** Passed through to the OPC 10000-4 `Like` matcher. */
17
+ likeOptions?: LikeOptions;
18
+ /**
19
+ * Accept `AddAliasesToCategory` entries whose target is on another Server.
20
+ *
21
+ * Off by default. Clause 6.3.4 Table 10 makes `Bad_NotSupported` an
22
+ * explicitly allowed answer — *"Support for remote Server TargetNodes is
23
+ * optional"* — and storing a reference this Server can never resolve or
24
+ * verify is a poor default. When on, such entries are accepted and reported
25
+ * `Uncertain_ReferenceOutOfServer`, since this Server does not check Nodes
26
+ * on other Servers.
27
+ */
28
+ allowRemoteTargets?: boolean;
29
+ }
30
+ export declare class AddressSpaceAliasStore implements IAliasStore {
31
+ private readonly addressSpace;
32
+ private readonly likeOptions?;
33
+ /** Per-category `LastChange`, as a VersionTime (clause 6.3.1). */
34
+ private readonly lastChangeByCategory;
35
+ private readonly allowRemoteTargets;
36
+ constructor(addressSpace: IAddressSpace, options?: AddressSpaceAliasStoreOptions);
37
+ /**
38
+ * Every alias at or below `query.categoryNodeId` matching the pattern.
39
+ *
40
+ * The search is recursive from the category the Method was called on
41
+ * (clause 6.3.1), so a call on `Aliases` also covers `TagVariables`,
42
+ * `Topics` and anything nested below them.
43
+ *
44
+ * One entry is produced per (AliasName, category) pair: `FindAliasVerbose`
45
+ * has to name the category that actually held the alias, which for a nested
46
+ * hit is the nested one, not the one that was called.
47
+ */
48
+ find(query: AliasQuery): Promise<AliasEntry[]>;
49
+ /** `LastChange` for a category, rolled up from its descendants (clause 6.3.1). */
50
+ lastChange(categoryNodeId: NodeId): number;
51
+ /**
52
+ * Record that a category changed, at `versionTime` (defaulting to now).
53
+ *
54
+ * Only the category itself is stored; the rollup to ancestors happens on
55
+ * read, so a category that is later re-parented reports correctly without
56
+ * anything having to be recomputed.
57
+ */
58
+ touch(categoryNodeId: NodeId, versionTime?: number): number;
59
+ /** Restore persisted `LastChange` values (clause 6.3.1: "shall be persisted"). */
60
+ restoreLastChange(values: Iterable<readonly [string, number]>): void;
61
+ /** Snapshot the per-category `LastChange` values for persistence. */
62
+ snapshotLastChange(): Array<[string, number]>;
63
+ /**
64
+ * Add aliases to a category (clause 6.3.4), one StatusCode per entry.
65
+ *
66
+ * The per-item codes of Table 10:
67
+ *
68
+ * - `Bad_NodeIdInvalid` — the NodeId is syntactically unusable.
69
+ * - `Bad_NodeIdUnknown` — the target is on this Server and does not exist.
70
+ * - `Uncertain_ReferenceOutOfServer` — the target is on another Server. The
71
+ * clause is explicit that this is returned **whether or not** a check was
72
+ * performed: *"If the Server does not check for the external Node's
73
+ * existence, it shall return Uncertain_ReferenceOutOfServer."* This Server
74
+ * does not check, because checking means being a Client of the other
75
+ * Server, which is the aggregation these packages exclude by design.
76
+ * - `Bad_NotSupported` — when {@link AddressSpaceAliasStoreOptions.allowRemoteTargets}
77
+ * is off, which Table 10 explicitly permits.
78
+ *
79
+ * An exact duplicate of (AliasName, target, target Server) is `Good` and
80
+ * ignored, whether it was already stored or repeated within this call.
81
+ */
82
+ add(categoryNodeId: NodeId, entries: AliasEntry[]): StatusCode[];
83
+ /**
84
+ * Remove aliases from a category (clause 6.3.5), one StatusCode per entry.
85
+ *
86
+ * `Bad_NotFound` when the name is not in the category, `Bad_InvalidState`
87
+ * when it is there but not owned by this Server — clause 6.3.5 opens by
88
+ * saying a Server "shall only delete AliasName instances that are defined on
89
+ * the Server exposing this Method".
90
+ *
91
+ * An entry with no target removes every target of that name. Removal is
92
+ * all-or-nothing per name: if any target cannot go, none of that name's do.
93
+ */
94
+ delete(categoryNodeId: NodeId, entries: Pick<AliasEntry, "aliasName" | "referencedNodes">[]): StatusCode[];
95
+ /** Add an alias whose target is on this Server. */
96
+ private addLocal;
97
+ /**
98
+ * Add an alias whose target is on another Server.
99
+ *
100
+ * Always `Uncertain_ReferenceOutOfServer`: this Server does not verify
101
+ * Nodes on other Servers, and clause 6.3.4 says that case returns the
102
+ * uncertain code rather than success.
103
+ */
104
+ private addRemote;
105
+ /** True when none of the alias's targets are on this Server. */
106
+ private isForeign;
107
+ /** The URI of a namespace index, or undefined for namespace 0. */
108
+ private namespaceUriOf;
109
+ /**
110
+ * Resolve the `ReferenceTypeFilter` argument.
111
+ *
112
+ * A null or absent NodeId means any ReferenceType (clause 6.3.2 Table 3).
113
+ */
114
+ private resolveReferenceTypeFilter;
115
+ /**
116
+ * The Nodes an alias points at.
117
+ *
118
+ * `findReferencesEx` already includes subtypes of the ReferenceType, which
119
+ * is what clause 6.3.2 Table 3 asks for: "Any ReferenceType includes all
120
+ * subtypes of that ReferenceType".
121
+ *
122
+ * An absent filter falls back to `AliasFor` rather than to *every*
123
+ * ReferenceType. Table 3 describes the filter as "AliasFor or one of its
124
+ * subtypes", and clause 8.2 makes `AliasFor` the ReferenceType that links an
125
+ * AliasName to what it names; taking "any" literally would return the
126
+ * alias's `HasTypeDefinition` target and its Organizes back-reference, which
127
+ * are not things the alias names.
128
+ */
129
+ private targetsOf;
130
+ }