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,417 @@
1
+ "use strict";
2
+ /**
3
+ * @module node-opcua-alias-name-server
4
+ *
5
+ * Binding the Methods of a single `AliasNameCategoryType` instance, and creating
6
+ * new categories at runtime.
7
+ *
8
+ * This is the one binding path. `installAliasNamesOnAddressSpace` calls
9
+ * {@link bindAliasCategory} in its loop rather than doing the work itself, so a
10
+ * category created after installation cannot end up bound differently from one
11
+ * that was there at install time — or, worse, not bound at all. An unbound
12
+ * MANDATORY `FindAlias` is the exact defect this package exists to remove, and
13
+ * it should not be able to reappear at runtime.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.INSTALLED = void 0;
17
+ exports.bindAliasCategory = bindAliasCategory;
18
+ exports.ensureLastChangeProperty = ensureLastChangeProperty;
19
+ exports.addAliasCategory = addAliasCategory;
20
+ exports.removeAliasCategory = removeAliasCategory;
21
+ exports.findMethodByDeclaration = findMethodByDeclaration;
22
+ exports.ensureOptionalMethod = ensureOptionalMethod;
23
+ exports.getInstalledAliasNames = getInstalledAliasNames;
24
+ exports.setInstalledAliasNames = setInstalledAliasNames;
25
+ const node_opcua_data_model_1 = require("node-opcua-data-model");
26
+ const node_opcua_nodeid_1 = require("node-opcua-nodeid");
27
+ const node_opcua_variant_1 = require("node-opcua-variant");
28
+ const bind_configuration_methods_js_1 = require("./bind_configuration_methods.js");
29
+ const bind_find_alias_js_1 = require("./bind_find_alias.js");
30
+ const last_change_js_1 = require("./last_change.js");
31
+ const well_known_js_1 = require("./well_known.js");
32
+ /**
33
+ * Bind `FindAlias` — and, when `verbose`, `FindAliasVerbose` — on one
34
+ * `AliasNameCategoryType` instance.
35
+ *
36
+ * Safe to call on a category that is already bound: `bindMethod` replaces the
37
+ * handler, and the optional Method is only added when it is missing.
38
+ *
39
+ * Use this for a category created after `installAliasNames` has run. The options
40
+ * that installation used are on {@link InstallAliasNamesResult.bindingOptions},
41
+ * so a caller does not have to reassemble them and risk binding a late category
42
+ * with a different store or a different result cap.
43
+ */
44
+ function bindAliasCategory(addressSpace, category, options) {
45
+ const findAlias = findMethodByDeclaration(category, well_known_js_1.MethodDeclarations.FindAlias, "FindAlias");
46
+ findAlias?.bindMethod((0, bind_find_alias_js_1.makeFindAliasHandler)(options, false));
47
+ if (options.verbose ?? true) {
48
+ const verbose = ensureOptionalMethod(addressSpace, category, "FindAliasVerbose");
49
+ verbose?.bindMethod((0, bind_find_alias_js_1.makeFindAliasHandler)(options, true));
50
+ }
51
+ if (options.lastChangeProperty ?? true) {
52
+ ensureLastChangeProperty(addressSpace, category);
53
+ }
54
+ // The write surface only appears when asked for (clause 6.3.4 / 6.3.5 are
55
+ // both Optional), and even then every call is denied unless isWriteAllowed
56
+ // says otherwise.
57
+ if (options.configurationMethods) {
58
+ const configurationOptions = {
59
+ store: options.store,
60
+ isWriteAllowed: options.isWriteAllowed,
61
+ onChanged: options.onChanged
62
+ };
63
+ const add = ensureOptionalMethod(addressSpace, category, "AddAliasesToCategory");
64
+ add?.bindMethod((0, bind_configuration_methods_js_1.makeAddAliasesToCategoryHandler)(configurationOptions));
65
+ const remove = ensureOptionalMethod(addressSpace, category, "DeleteAliasesFromCategory");
66
+ remove?.bindMethod((0, bind_configuration_methods_js_1.makeDeleteAliasesFromCategoryHandler)(configurationOptions));
67
+ }
68
+ }
69
+ /**
70
+ * The default NodeId for a new category: a **string** NodeId spelling out its
71
+ * path under `Aliases`, for instance `ns=1;s=Aliases/TagVariables/Unit200`.
72
+ *
73
+ * The obvious alternative — letting the namespace assign the next free numeric
74
+ * id — is wrong here for two reasons.
75
+ *
76
+ * It is **not stable across restarts**. The counter depends on how many other
77
+ * Nodes were created first, so adding one unrelated Variable to a Server shifts
78
+ * every category's NodeId. That silently breaks `LastChange` persistence, which
79
+ * keys on the category NodeId: the restored values no longer match any
80
+ * category, `LastChange` reads 0, and clause 6.3.1 then requires every connected
81
+ * Client to clear a cache that was perfectly valid. A Server-side change with a
82
+ * purely remote symptom.
83
+ *
84
+ * It is also **not diagnosable**. `ns=1;i=1010` in a log or a
85
+ * `FindAliasVerbose` result says nothing; `ns=1;s=Aliases/TagVariables/Unit200`
86
+ * says which category it is without a lookup.
87
+ *
88
+ * The path is unique because two categories cannot share a parent and a
89
+ * BrowseName, and it is derived from the same information every run, so it is
90
+ * the same NodeId every run.
91
+ */
92
+ function defaultCategoryNodeId(parent, browseName, namespaceIndex) {
93
+ const path = [...categoryPathOf(parent), browseName].join("/");
94
+ return new node_opcua_nodeid_1.NodeId(node_opcua_nodeid_1.NodeIdType.STRING, path, namespaceIndex);
95
+ }
96
+ /**
97
+ * The BrowseNames from the `Aliases` root down to `category`, inclusive.
98
+ *
99
+ * Falls back to the category's own BrowseName when it is not under the root,
100
+ * which keeps the id derivable for a category modelled outside the standard
101
+ * hierarchy.
102
+ */
103
+ function categoryPathOf(category) {
104
+ const segments = [];
105
+ const seen = new Set();
106
+ let current = category;
107
+ while (current) {
108
+ const key = current.nodeId.toString();
109
+ if (seen.has(key)) {
110
+ break;
111
+ }
112
+ seen.add(key);
113
+ segments.unshift(current.browseName.name ?? key);
114
+ if (key === well_known_js_1.WellKnownCategories.Aliases.toString()) {
115
+ break;
116
+ }
117
+ const parents = current.findReferencesExAsObject("HierarchicalReferences", node_opcua_data_model_1.BrowseDirection.Inverse);
118
+ const next = parents.find((p) => p.nodeClass === node_opcua_data_model_1.NodeClass.Object);
119
+ current = next ? next : null;
120
+ }
121
+ return segments;
122
+ }
123
+ /**
124
+ * Ensure a category has a `LastChange` Property.
125
+ *
126
+ * `LastChange` is Optional on `AliasNameCategoryType` and the shipped nodeset
127
+ * instantiates it only on the `Aliases` root, which clause 9.2 makes mandatory.
128
+ * Adding it to every category is conformant — Optional means may, not must not —
129
+ * and it is what makes the clause 6.3.1 rollup observable: without it, a Client
130
+ * watching one branch has nothing to watch.
131
+ */
132
+ function ensureLastChangeProperty(addressSpace, category) {
133
+ const existing = category.getPropertyByName(last_change_js_1.LAST_CHANGE_BROWSE_NAME);
134
+ if (existing) {
135
+ return existing;
136
+ }
137
+ const namespace = addressSpace.getNamespace(category.nodeId.namespace === 0 ? addressSpace.getOwnNamespace().index : category.nodeId.namespace);
138
+ return namespace.addVariable({
139
+ propertyOf: category,
140
+ browseName: last_change_js_1.LAST_CHANGE_BROWSE_NAME,
141
+ // VersionTime (i=20998) is a UInt32 subtype, not a DateTime
142
+ dataType: well_known_js_1.VERSION_TIME_DATA_TYPE,
143
+ minimumSamplingInterval: 1000,
144
+ value: { dataType: node_opcua_variant_1.DataType.UInt32, value: 0 }
145
+ });
146
+ }
147
+ /**
148
+ * Create a vendor `AliasNameCategoryType` instance under `parent` **and bind it**.
149
+ *
150
+ * Creating one by hand means instantiating the type, wiring the `Organizes`
151
+ * reference and then remembering to bind — and a category whose `FindAlias` is
152
+ * unbound fails conformance silently. This does all three.
153
+ *
154
+ * When `installAliasNames` has already run on this address space, the binding
155
+ * options it used are reused unless overridden, so a category added at runtime
156
+ * behaves exactly like one that was present at install time. Pass a `store`
157
+ * explicitly if installation has not run yet.
158
+ */
159
+ function addAliasCategory(addressSpace, parent, browseName, options) {
160
+ const parentNode = coerceCategoryNode(addressSpace, parent);
161
+ const categoryType = resolveCategoryType(addressSpace, options?.categoryType);
162
+ const namespace = addressSpace.getNamespace(options?.namespaceIndex ?? addressSpace.getOwnNamespace().index);
163
+ const nodeId = options?.nodeId ?? defaultCategoryNodeId(parentNode, browseName, namespace.index);
164
+ if (addressSpace.findNode(nodeId)) {
165
+ throw new Error(`addAliasCategory: ${nodeId.toString()} already exists. A category's default NodeId is derived from its ` +
166
+ "path under Aliases, so this means a category of the same name already exists under the same parent.");
167
+ }
168
+ const category = categoryType.instantiate({
169
+ browseName: { name: browseName, namespaceIndex: namespace.index },
170
+ nodeId,
171
+ organizedBy: parentNode,
172
+ namespace
173
+ });
174
+ if (options?.rolePermissions) {
175
+ // instantiate() does not take them, so they are applied after
176
+ category.setRolePermissions(options.rolePermissions);
177
+ }
178
+ const bindingOptions = resolveBindingOptions(addressSpace, options);
179
+ if (bindingOptions) {
180
+ bindAliasCategory(addressSpace, category, bindingOptions);
181
+ }
182
+ // clause 6.3.1: "The last time an AliasNameCategory was added or deleted"
183
+ notifyCategoryChanged(addressSpace, parentNode.nodeId);
184
+ return category;
185
+ }
186
+ /**
187
+ * Resolve the ObjectType to instantiate, defaulting to `AliasNameCategoryType`.
188
+ *
189
+ * A subtype is accepted: discovery matches on "is this an instance of
190
+ * AliasNameCategoryType *or a subtype*", and binding looks the Methods up by
191
+ * MethodDeclarationId, so neither cares which exact type was used.
192
+ */
193
+ function resolveCategoryType(addressSpace, categoryType) {
194
+ const base = addressSpace.findObjectType(well_known_js_1.ALIAS_NAME_CATEGORY_TYPE);
195
+ if (!base) {
196
+ throw new Error("addAliasCategory: AliasNameCategoryType (i=23456) is not in the address space");
197
+ }
198
+ if (!categoryType) {
199
+ return base;
200
+ }
201
+ const resolved = categoryType instanceof node_opcua_nodeid_1.NodeId ? addressSpace.findObjectType(categoryType) : categoryType;
202
+ if (!resolved) {
203
+ throw new Error(`addAliasCategory: unknown ObjectType ${String(categoryType)}`);
204
+ }
205
+ if (resolved.nodeId.value !== base.nodeId.value && !resolved.isSubtypeOf(base)) {
206
+ throw new Error(`addAliasCategory: ${resolved.browseName.toString()} is not AliasNameCategoryType or a subtype of it`);
207
+ }
208
+ return resolved;
209
+ }
210
+ /**
211
+ * Remove a category, and decide what happens to what it Organizes.
212
+ *
213
+ * The specification does not say, so the rule is stated here rather than left to
214
+ * whatever `deleteNode` happens to do:
215
+ *
216
+ * - **`reparent`** (the default) moves the category's aliases and subcategories
217
+ * to its parent before deleting it. Nothing disappears, so a Client that had
218
+ * resolved an alias keeps resolving it — the alias Object keeps its NodeId,
219
+ * and clause 6.2 makes a NodeId change mean "this is a different alias".
220
+ * - **`cascade`** deletes them with it. Correct when the category *is* the
221
+ * thing being retired, such as a tenant being removed.
222
+ *
223
+ * Refuses to remove one of the three well-known categories, which clause 9
224
+ * requires a Server to have.
225
+ *
226
+ * @returns the aliases and subcategories that were re-parented, or deleted.
227
+ */
228
+ function removeAliasCategory(addressSpace, category, options) {
229
+ const node = coerceCategoryNode(addressSpace, category);
230
+ for (const wellKnown of Object.values(well_known_js_1.WellKnownCategories)) {
231
+ if (wellKnown.value === node.nodeId.value && wellKnown.namespace === node.nodeId.namespace) {
232
+ throw new Error(`removeAliasCategory: ${node.browseName.toString()} is a well-known category that ` +
233
+ "OPC 10000-17 clause 9 requires the Server to have");
234
+ }
235
+ }
236
+ const parents = node.findReferencesExAsObject("HierarchicalReferences", node_opcua_data_model_1.BrowseDirection.Inverse);
237
+ // Organizes only, not every hierarchical reference. A category's Methods are
238
+ // HasComponent children that belong to it and must go with it; re-parenting
239
+ // those would leave the parent with a second FindAlias.
240
+ const childReferences = node.findReferencesEx("Organizes", node_opcua_data_model_1.BrowseDirection.Forward);
241
+ const orphans = options?.orphans ?? "reparent";
242
+ const moved = [];
243
+ const deleted = [];
244
+ if (orphans === "reparent") {
245
+ const parent = parents[0];
246
+ if (!parent) {
247
+ throw new Error(`removeAliasCategory: ${node.browseName.toString()} has no parent to re-parent its contents to; ` +
248
+ 'pass { orphans: "cascade" } to delete them instead');
249
+ }
250
+ for (const reference of childReferences) {
251
+ parent.addReference({ referenceType: reference.referenceType, nodeId: reference.nodeId });
252
+ // Detach before deleting: deleteNode cascades through Organizes, so
253
+ // a child still referenced here would be deleted along with the
254
+ // category despite having just been re-parented.
255
+ node.removeReference({ referenceType: reference.referenceType, nodeId: reference.nodeId });
256
+ moved.push(reference.nodeId);
257
+ }
258
+ }
259
+ else {
260
+ for (const reference of childReferences) {
261
+ deleted.push(reference.nodeId);
262
+ }
263
+ }
264
+ // whatever is still attached goes with it
265
+ addressSpace.deleteNode(node.nodeId);
266
+ // clause 6.3.1: a category was deleted
267
+ for (const parent of parents) {
268
+ notifyCategoryChanged(addressSpace, parent.nodeId);
269
+ }
270
+ return { moved, deleted };
271
+ }
272
+ /**
273
+ * Tell the installed `LastChange` tracker that a category's contents changed.
274
+ *
275
+ * Fire and forget: the Property is written synchronously and only the
276
+ * persistence write is async, so a failure to persist must not fail the
277
+ * caller's structural change.
278
+ */
279
+ function notifyCategoryChanged(addressSpace, categoryNodeId) {
280
+ const installed = getInstalledAliasNames(addressSpace);
281
+ void installed?.lastChange?.touch(categoryNodeId);
282
+ }
283
+ /**
284
+ * Merge explicit options over whatever installation recorded, or return null
285
+ * when there is nothing to bind with.
286
+ */
287
+ function resolveBindingOptions(addressSpace, options) {
288
+ const installed = getInstalledAliasNames(addressSpace);
289
+ const inherited = installed?.bindingOptions;
290
+ const store = options?.store ?? inherited?.store;
291
+ if (!store) {
292
+ // nothing to bind against yet; installAliasNames will pick this category
293
+ // up when it runs, since it is Organized below its parent
294
+ return null;
295
+ }
296
+ // Inherit by spreading rather than by listing fields. Cherry-picking meant
297
+ // every new binding option had to be remembered here too, and forgetting one
298
+ // let a category created at runtime diverge from an installed one - silently,
299
+ // and in whichever direction was least safe.
300
+ const merged = {
301
+ ...inherited,
302
+ store,
303
+ maxResults: options?.maxResults ?? inherited?.maxResults ?? well_known_js_1.DEFAULT_MAX_RESULTS
304
+ };
305
+ // Only keys the caller actually supplied override the inherited value; an
306
+ // absent key must not read as "false".
307
+ for (const key of Object.keys(options ?? {})) {
308
+ const value = options?.[key];
309
+ if (value === undefined ||
310
+ key === "namespaceIndex" ||
311
+ key === "nodeId" ||
312
+ key === "categoryType" ||
313
+ key === "rolePermissions") {
314
+ continue;
315
+ }
316
+ Object.assign(merged, { [key]: value });
317
+ }
318
+ return merged;
319
+ }
320
+ /** Accept a category node or its NodeId. */
321
+ function coerceCategoryNode(addressSpace, node) {
322
+ if (!(node instanceof node_opcua_nodeid_1.NodeId)) {
323
+ return node;
324
+ }
325
+ const found = addressSpace.findNode(node);
326
+ if (!found || found.nodeClass !== node_opcua_data_model_1.NodeClass.Object) {
327
+ throw new Error(`addAliasCategory: ${node.toString()} is not an Object in this address space`);
328
+ }
329
+ return found;
330
+ }
331
+ /**
332
+ * Find a Method on a category by its MethodDeclarationId, falling back to the
333
+ * BrowseName.
334
+ *
335
+ * The declaration id is the reliable key: a Server may publish the Method under
336
+ * a localised DisplayName, and the BrowseName is only unique within the
337
+ * namespace. The fallback covers instances built in code, which do not always
338
+ * carry a `methodDeclarationId`.
339
+ */
340
+ function findMethodByDeclaration(category, declarationId, browseName) {
341
+ for (const component of category.getComponents()) {
342
+ if (component.nodeClass !== node_opcua_data_model_1.NodeClass.Method) {
343
+ continue;
344
+ }
345
+ const method = component;
346
+ if (method.methodDeclarationId && method.methodDeclarationId.value === declarationId.value) {
347
+ return method;
348
+ }
349
+ if (method.browseName.name === browseName) {
350
+ return method;
351
+ }
352
+ }
353
+ return null;
354
+ }
355
+ /**
356
+ * Ensure an optional Method exists on a category, adding it when the nodeset
357
+ * only declared it on the type.
358
+ *
359
+ * The shipped `Opc.Ua.NodeSet2.xml` declares `FindAliasVerbose`,
360
+ * `AddAliasesToCategory` and `DeleteAliasesFromCategory` on
361
+ * `AliasNameCategoryType` but instantiates none of them on `Aliases`,
362
+ * `TagVariables` or `Topics`. Upstream nonetheless reserves fixed NodeIds for
363
+ * those instances, so where one exists it is used in preference to a
364
+ * server-assigned id; an aggregating Server then sees the NodeId it expects.
365
+ */
366
+ function ensureOptionalMethod(addressSpace, category, name) {
367
+ const declarationId = well_known_js_1.MethodDeclarations[name];
368
+ const existing = findMethodByDeclaration(category, declarationId, name);
369
+ if (existing) {
370
+ return existing;
371
+ }
372
+ const declaration = addressSpace.findNode(declarationId);
373
+ if (!declaration || declaration.nodeClass !== node_opcua_data_model_1.NodeClass.Method) {
374
+ // an address space whose nodeset predates the optional Methods
375
+ return null;
376
+ }
377
+ const reservedNodeId = reservedMethodNodeId(category.nodeId, name);
378
+ // a reserved id already taken by something else means the address space is
379
+ // not what we think it is; fall back to a server-assigned id rather than
380
+ // colliding
381
+ const nodeId = reservedNodeId && !addressSpace.findNode(reservedNodeId) ? reservedNodeId : undefined;
382
+ return declaration.clone({
383
+ namespace: addressSpace.getNamespace(category.nodeId.namespace),
384
+ nodeId,
385
+ componentOf: category,
386
+ methodDeclarationId: declarationId
387
+ });
388
+ }
389
+ /** The NodeId OPC 10000-17 reserves for an optional Method on a well-known category. */
390
+ function reservedMethodNodeId(categoryNodeId, name) {
391
+ for (const [key, wellKnownId] of Object.entries(well_known_js_1.WellKnownCategories)) {
392
+ if (wellKnownId.value === categoryNodeId.value && wellKnownId.namespace === categoryNodeId.namespace) {
393
+ return well_known_js_1.WellKnownOptionalMethods[key][name];
394
+ }
395
+ }
396
+ return undefined;
397
+ }
398
+ /**
399
+ * Marks an address space as already carrying AliasName bindings, so a second
400
+ * `installAliasNames` is a no-op rather than a double binding.
401
+ */
402
+ exports.INSTALLED = Symbol.for("node-opcua-alias-name-server.installed");
403
+ /**
404
+ * What `installAliasNames` recorded on this address space, or undefined if it
405
+ * has not run.
406
+ *
407
+ * Exposed so a caller can rebind a late category with exactly the options
408
+ * installation used, without having to keep the install result around.
409
+ */
410
+ function getInstalledAliasNames(addressSpace) {
411
+ return addressSpace[exports.INSTALLED];
412
+ }
413
+ /** Record the installation on the address space. */
414
+ function setInstalledAliasNames(addressSpace, value) {
415
+ addressSpace[exports.INSTALLED] = value;
416
+ }
417
+ //# sourceMappingURL=bind_alias_category.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind_alias_category.js","sourceRoot":"","sources":["../source/bind_alias_category.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @module node-opcua-alias-name-server
3
+ *
4
+ * `AddAliasesToCategory` (clause 6.3.4) and `DeleteAliasesFromCategory`
5
+ * (clause 6.3.5) — the *AliasName Configuration Support* facet, CU 5874.
6
+ *
7
+ * Both report **per item**: the Method itself succeeds and an `ErrorCodes` array
8
+ * parallel to `AliasNames` says what happened to each one. A single bad entry
9
+ * does not fail the call, which is why the store interface returns
10
+ * `StatusCode[]` rather than throwing.
11
+ */
12
+ import type { ISessionContext, UAMethod } from "node-opcua-address-space-base";
13
+ import type { IAliasStore } from "node-opcua-alias-name-common";
14
+ import { type NodeId } from "node-opcua-nodeid";
15
+ import type { CallMethodResultOptions } from "node-opcua-service-call";
16
+ import { type Variant } from "node-opcua-variant";
17
+ export interface ConfigurationBindingOptions {
18
+ /** The store that performs the mutation. Must implement `add` / `delete`. */
19
+ store: IAliasStore;
20
+ /**
21
+ * Write gate (clause 6.3.4 Table 11 / 6.3.5 Table 15). **Defaults to denying
22
+ * everyone** — the write surface is the one place a permissive default would
23
+ * be a security defect rather than a convenience.
24
+ */
25
+ isWriteAllowed?: (context: ISessionContext, categoryNodeId: NodeId) => boolean | Promise<boolean>;
26
+ /** Called after a successful mutation so `LastChange` can move. */
27
+ onChanged?: (categoryNodeId: NodeId) => void | Promise<void>;
28
+ }
29
+ /**
30
+ * Handler for `AddAliasesToCategory` (clause 6.3.4).
31
+ *
32
+ * Table 11 governs the *call*: `Bad_InvalidArgument` when an argument is the
33
+ * wrong type, when the arrays other than `TargetServers` differ in length, or
34
+ * when all arrays are empty. Table 10 governs each *item*.
35
+ */
36
+ export declare function makeAddAliasesToCategoryHandler(options: ConfigurationBindingOptions): (this: UAMethod, inputArguments: Variant[], context: ISessionContext) => Promise<CallMethodResultOptions>;
37
+ /**
38
+ * Handler for `DeleteAliasesFromCategory` (clause 6.3.5).
39
+ *
40
+ * Table 15 governs the call: unlike Add, **every** array must be the same
41
+ * length — "the size of the arrays for all arguments is not the same", with no
42
+ * exception, because there is no `TargetServers` here.
43
+ */
44
+ export declare function makeDeleteAliasesFromCategoryHandler(options: ConfigurationBindingOptions): (this: UAMethod, inputArguments: Variant[], context: ISessionContext) => Promise<CallMethodResultOptions>;
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ /**
3
+ * @module node-opcua-alias-name-server
4
+ *
5
+ * `AddAliasesToCategory` (clause 6.3.4) and `DeleteAliasesFromCategory`
6
+ * (clause 6.3.5) — the *AliasName Configuration Support* facet, CU 5874.
7
+ *
8
+ * Both report **per item**: the Method itself succeeds and an `ErrorCodes` array
9
+ * parallel to `AliasNames` says what happened to each one. A single bad entry
10
+ * does not fail the call, which is why the store interface returns
11
+ * `StatusCode[]` rather than throwing.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.makeAddAliasesToCategoryHandler = makeAddAliasesToCategoryHandler;
15
+ exports.makeDeleteAliasesFromCategoryHandler = makeDeleteAliasesFromCategoryHandler;
16
+ const node_opcua_nodeid_1 = require("node-opcua-nodeid");
17
+ const node_opcua_status_code_1 = require("node-opcua-status-code");
18
+ const node_opcua_variant_1 = require("node-opcua-variant");
19
+ const well_known_js_1 = require("./well_known.js");
20
+ /** Read a String[] argument, tolerating null for "empty". */
21
+ function readStringArray(inputArguments, index) {
22
+ const value = inputArguments?.[index]?.value;
23
+ if (value === null || value === undefined) {
24
+ return [];
25
+ }
26
+ if (!Array.isArray(value)) {
27
+ return null;
28
+ }
29
+ return value.map((v) => (typeof v === "string" ? v : String(v)));
30
+ }
31
+ /** Read an ExpandedNodeId[] argument, tolerating null for "empty". */
32
+ function readNodeIdArray(inputArguments, index) {
33
+ const value = inputArguments?.[index]?.value;
34
+ if (value === null || value === undefined) {
35
+ return [];
36
+ }
37
+ if (!Array.isArray(value)) {
38
+ return null;
39
+ }
40
+ return value;
41
+ }
42
+ /** Build the OutputArguments Variant for an ErrorCodes array. */
43
+ function errorCodesResult(codes) {
44
+ return {
45
+ statusCode: node_opcua_status_code_1.StatusCodes.Good,
46
+ outputArguments: [
47
+ {
48
+ dataType: node_opcua_variant_1.DataType.StatusCode,
49
+ arrayType: node_opcua_variant_1.VariantArrayType.Array,
50
+ value: codes
51
+ }
52
+ ]
53
+ };
54
+ }
55
+ /**
56
+ * Handler for `AddAliasesToCategory` (clause 6.3.4).
57
+ *
58
+ * Table 11 governs the *call*: `Bad_InvalidArgument` when an argument is the
59
+ * wrong type, when the arrays other than `TargetServers` differ in length, or
60
+ * when all arrays are empty. Table 10 governs each *item*.
61
+ */
62
+ function makeAddAliasesToCategoryHandler(options) {
63
+ return async function addAliasesToCategoryHandler(inputArguments, context) {
64
+ const category = this.parent;
65
+ if (!category) {
66
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadInternalError };
67
+ }
68
+ // clause 6.3.4 Table 11
69
+ if (!(await isWriteAllowed(options, context, category.nodeId))) {
70
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied };
71
+ }
72
+ const aliasNames = readStringArray(inputArguments, 0);
73
+ const targetNodes = readNodeIdArray(inputArguments, 1);
74
+ const targetServers = readStringArray(inputArguments, 2);
75
+ const targetReferenceTypeRaw = inputArguments?.[3]?.value;
76
+ if (aliasNames === null || targetNodes === null || targetServers === null) {
77
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
78
+ }
79
+ // "the size of the arrays for all arguments except TargetServers is not
80
+ // the same" - TargetServers is excluded because Table 9 lets it be null
81
+ // or empty to mean "all local"
82
+ if (aliasNames.length !== targetNodes.length) {
83
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
84
+ }
85
+ // "or if all arrays are empty"
86
+ if (aliasNames.length === 0) {
87
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
88
+ }
89
+ if (targetServers.length !== 0 && targetServers.length !== aliasNames.length) {
90
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
91
+ }
92
+ // Table 9: "If null, it defaults to AliasFor."
93
+ const referenceTypeId = targetReferenceTypeRaw instanceof node_opcua_nodeid_1.NodeId && !targetReferenceTypeRaw.isEmpty() ? targetReferenceTypeRaw : well_known_js_1.ALIAS_FOR;
94
+ const entries = aliasNames.map((aliasName, i) => {
95
+ // Table 9: "The ServerIndex in the ExpandedNodeId shall be ignored
96
+ // and the TargetServers Uri shall be used."
97
+ const serverUri = targetServers[i] ? targetServers[i] : null;
98
+ return {
99
+ aliasName,
100
+ referencedNodes: [targetNodes[i]],
101
+ serverUris: [serverUri],
102
+ categoryNodeId: category.nodeId,
103
+ referenceTypeIds: [referenceTypeId]
104
+ };
105
+ });
106
+ if (!options.store.add) {
107
+ // a read-only store: every item is unsupported, but the call itself
108
+ // succeeded in reporting that
109
+ return errorCodesResult(entries.map(() => node_opcua_status_code_1.StatusCodes.BadNotSupported));
110
+ }
111
+ const codes = await options.store.add(category.nodeId, entries);
112
+ if (codes.some((code) => code.isGood())) {
113
+ await options.onChanged?.(category.nodeId);
114
+ }
115
+ return errorCodesResult(codes);
116
+ };
117
+ }
118
+ /**
119
+ * Handler for `DeleteAliasesFromCategory` (clause 6.3.5).
120
+ *
121
+ * Table 15 governs the call: unlike Add, **every** array must be the same
122
+ * length — "the size of the arrays for all arguments is not the same", with no
123
+ * exception, because there is no `TargetServers` here.
124
+ */
125
+ function makeDeleteAliasesFromCategoryHandler(options) {
126
+ return async function deleteAliasesFromCategoryHandler(inputArguments, context) {
127
+ const category = this.parent;
128
+ if (!category) {
129
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadInternalError };
130
+ }
131
+ if (!(await isWriteAllowed(options, context, category.nodeId))) {
132
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied };
133
+ }
134
+ const aliasNames = readStringArray(inputArguments, 0);
135
+ const targetNodes = readNodeIdArray(inputArguments, 1);
136
+ if (aliasNames === null || targetNodes === null) {
137
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
138
+ }
139
+ if (aliasNames.length === 0) {
140
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
141
+ }
142
+ // Table 13: "The length of each of the arrays shall be the same." A null
143
+ // TargetNodes array is the documented way to say "every target", so an
144
+ // empty array is accepted and expanded.
145
+ if (targetNodes.length !== 0 && targetNodes.length !== aliasNames.length) {
146
+ return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
147
+ }
148
+ const entries = aliasNames.map((aliasName, i) => {
149
+ // "If the TargetNodes array entry is null or empty, all AliasNames
150
+ // with the provided name are deleted from the AliasNameCategory."
151
+ const target = targetNodes[i];
152
+ const referencedNodes = target && !target.isEmpty() ? [target] : [];
153
+ return { aliasName, referencedNodes };
154
+ });
155
+ if (!options.store.delete) {
156
+ return errorCodesResult(entries.map(() => node_opcua_status_code_1.StatusCodes.BadNotSupported));
157
+ }
158
+ const codes = await options.store.delete(category.nodeId, entries);
159
+ if (codes.some((code) => code.isGood())) {
160
+ await options.onChanged?.(category.nodeId);
161
+ }
162
+ return errorCodesResult(codes);
163
+ };
164
+ }
165
+ /** The write gate, defaulting to deny. */
166
+ async function isWriteAllowed(options, context, categoryNodeId) {
167
+ if (!options.isWriteAllowed) {
168
+ // Writing is off unless the Server says who may do it. OPC 10000-17
169
+ // defines no security model at all, so there is no safe default rule to
170
+ // fall back on - only a safe default answer.
171
+ return false;
172
+ }
173
+ return await options.isWriteAllowed(context, categoryNodeId);
174
+ }
175
+ //# sourceMappingURL=bind_configuration_methods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind_configuration_methods.js","sourceRoot":"","sources":["../source/bind_configuration_methods.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAoEH,0EAmEC;AASD,oFAiDC;AA7LD,yDAA4F;AAE5F,mEAAsE;AACtE,2DAA8E;AAC9E,mDAA4C;AAe5C,6DAA6D;AAC7D,SAAS,eAAe,CAAC,cAAyB,EAAE,KAAa;IAC7D,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAC7C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,sEAAsE;AACtE,SAAS,eAAe,CAAC,cAAyB,EAAE,KAAa;IAC7D,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAC7C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,KAAyB,CAAC;AACrC,CAAC;AAED,iEAAiE;AACjE,SAAS,gBAAgB,CAAC,KAAmB;IACzC,OAAO;QACH,UAAU,EAAE,oCAAW,CAAC,IAAI;QAC5B,eAAe,EAAE;YACb;gBACI,QAAQ,EAAE,6BAAQ,CAAC,UAAU;gBAC7B,SAAS,EAAE,qCAAgB,CAAC,KAAK;gBACjC,KAAK,EAAE,KAAK;aACf;SACJ;KACJ,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,+BAA+B,CAAC,OAAoC;IAChF,OAAO,KAAK,UAAU,2BAA2B,CAE7C,cAAyB,EACzB,OAAwB;QAExB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAyB,CAAC;QAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,OAAO,EAAE,UAAU,EAAE,oCAAW,CAAC,gBAAgB,EAAE,CAAC;QACxD,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC,CAAC,MAAM,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YAC7D,OAAO,EAAE,UAAU,EAAE,oCAAW,CAAC,mBAAmB,EAAE,CAAC;QAC3D,CAAC;QAED,MAAM,UAAU,GAAG,eAAe,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;QACtD,MAAM,WAAW,GAAG,eAAe,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;QACvD,MAAM,aAAa,GAAG,eAAe,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;QACzD,MAAM,sBAAsB,GAAG,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;QAE1D,IAAI,UAAU,KAAK,IAAI,IAAI,WAAW,KAAK,IAAI,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YACxE,OAAO,EAAE,UAAU,EAAE,oCAAW,CAAC,kBAAkB,EAAE,CAAC;QAC1D,CAAC;QACD,wEAAwE;QACxE,wEAAwE;QACxE,+BAA+B;QAC/B,IAAI,UAAU,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM,EAAE,CAAC;YAC3C,OAAO,EAAE,UAAU,EAAE,oCAAW,CAAC,kBAAkB,EAAE,CAAC;QAC1D,CAAC;QACD,+BAA+B;QAC/B,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,UAAU,EAAE,oCAAW,CAAC,kBAAkB,EAAE,CAAC;QAC1D,CAAC;QACD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;YAC3E,OAAO,EAAE,UAAU,EAAE,oCAAW,CAAC,kBAAkB,EAAE,CAAC;QAC1D,CAAC;QAED,+CAA+C;QAC/C,MAAM,eAAe,GACjB,sBAAsB,YAAY,0BAAW,IAAI,CAAC,sBAAsB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,yBAAS,CAAC;QAE5H,MAAM,OAAO,GAAiB,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE;YAC1D,mEAAmE;YACnE,4CAA4C;YAC5C,MAAM,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7D,OAAO;gBACH,SAAS;gBACT,eAAe,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;gBACjC,UAAU,EAAE,CAAC,SAAS,CAAC;gBACvB,cAAc,EAAE,QAAQ,CAAC,MAAM;gBAC/B,gBAAgB,EAAE,CAAC,eAAe,CAAC;aACtC,CAAC;QACN,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACrB,oEAAoE;YACpE,8BAA8B;YAC9B,OAAO,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,oCAAW,CAAC,eAAe,CAAC,CAAC,CAAC;QAC5E,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChE,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;YACtC,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,oCAAoC,CAAC,OAAoC;IACrF,OAAO,KAAK,UAAU,gCAAgC,CAElD,cAAyB,EACzB,OAAwB;QAExB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAyB,CAAC;QAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,OAAO,EAAE,UAAU,EAAE,oCAAW,CAAC,gBAAgB,EAAE,CAAC;QACxD,CAAC;QAED,IAAI,CAAC,CAAC,MAAM,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YAC7D,OAAO,EAAE,UAAU,EAAE,oCAAW,CAAC,mBAAmB,EAAE,CAAC;QAC3D,CAAC;QAED,MAAM,UAAU,GAAG,eAAe,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;QACtD,MAAM,WAAW,GAAG,eAAe,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;QAEvD,IAAI,UAAU,KAAK,IAAI,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YAC9C,OAAO,EAAE,UAAU,EAAE,oCAAW,CAAC,kBAAkB,EAAE,CAAC;QAC1D,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,UAAU,EAAE,oCAAW,CAAC,kBAAkB,EAAE,CAAC;QAC1D,CAAC;QACD,yEAAyE;QACzE,uEAAuE;QACvE,wCAAwC;QACxC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;YACvE,OAAO,EAAE,UAAU,EAAE,oCAAW,CAAC,kBAAkB,EAAE,CAAC;QAC1D,CAAC;QAED,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE;YAC5C,mEAAmE;YACnE,kEAAkE;YAClE,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAC9B,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACxB,OAAO,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,oCAAW,CAAC,eAAe,CAAC,CAAC,CAAC;QAC5E,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnE,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;YACtC,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,CAAC;AACN,CAAC;AAED,0CAA0C;AAC1C,KAAK,UAAU,cAAc,CACzB,OAAoC,EACpC,OAAwB,EACxB,cAAsB;IAEtB,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC1B,oEAAoE;QACpE,wEAAwE;QACxE,6CAA6C;QAC7C,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,MAAM,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;AACjE,CAAC"}