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,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module node-opcua-alias-name-server
|
|
3
|
+
*
|
|
4
|
+
* The `FindAlias` (clause 6.3.2) and `FindAliasVerbose` (clause 6.3.3) Method
|
|
5
|
+
* handlers.
|
|
6
|
+
*
|
|
7
|
+
* The two Methods are identical in every respect except the DataType they
|
|
8
|
+
* return, so both are produced from one implementation: whatever the FindAlias
|
|
9
|
+
* suite proves is proved for FindAliasVerbose too.
|
|
10
|
+
*/
|
|
11
|
+
import type { ISessionContext, UAMethod } from "node-opcua-address-space-base";
|
|
12
|
+
import { type AliasEntry, type IAliasStore } from "node-opcua-alias-name-common";
|
|
13
|
+
import { type NodeId } from "node-opcua-nodeid";
|
|
14
|
+
import type { CallMethodResultOptions } from "node-opcua-service-call";
|
|
15
|
+
import { type Variant } from "node-opcua-variant";
|
|
16
|
+
/**
|
|
17
|
+
* Orders results before they are returned.
|
|
18
|
+
*
|
|
19
|
+
* Clause 6.3.2 requires the Server to return "what it recommends as the best
|
|
20
|
+
* match first", and says the criteria are Server specific — the examples it
|
|
21
|
+
* gives (ServerStatus of the Server holding the Node, load balancing) only mean
|
|
22
|
+
* anything once more than one Server is involved. A Server publishing its own
|
|
23
|
+
* aliases has no basis to prefer one of its own Nodes over another, so the
|
|
24
|
+
* default preserves discovery order, which is at least deterministic and
|
|
25
|
+
* therefore stable across calls. Replace it when the Server does have a basis.
|
|
26
|
+
*/
|
|
27
|
+
export type AliasComparator = (a: AliasEntry, b: AliasEntry) => number;
|
|
28
|
+
/** The default: keep discovery order (a stable no-op comparator). */
|
|
29
|
+
export declare const insertionOrderComparator: AliasComparator;
|
|
30
|
+
export interface FindAliasBindingOptions {
|
|
31
|
+
/** Where the aliases come from. */
|
|
32
|
+
store: IAliasStore;
|
|
33
|
+
/**
|
|
34
|
+
* Beyond this many results the call fails with `Bad_ResponseTooLarge`
|
|
35
|
+
* (clause 6.3.2 Table 4).
|
|
36
|
+
*/
|
|
37
|
+
maxResults: number;
|
|
38
|
+
/** Result ordering; defaults to {@link insertionOrderComparator}. */
|
|
39
|
+
comparator?: AliasComparator;
|
|
40
|
+
/**
|
|
41
|
+
* Read gate. Return false to answer `Bad_UserAccessDenied`
|
|
42
|
+
* (clause 6.3.2 Table 4). Defaults to allowing everyone, matching a Server
|
|
43
|
+
* that publishes its aliases openly.
|
|
44
|
+
*
|
|
45
|
+
* Receives the category the Method was called on, so a Server with
|
|
46
|
+
* per-customer or per-tenant categories can answer "may this user see *this*
|
|
47
|
+
* category" rather than only "may this user read aliases at all". May return
|
|
48
|
+
* a Promise: the handler is async anyway, so a permission lookup that hits a
|
|
49
|
+
* database costs nothing structurally.
|
|
50
|
+
*/
|
|
51
|
+
isReadAllowed?: (context: ISessionContext, categoryNodeId: NodeId) => boolean | Promise<boolean>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Build a handler for `FindAlias` or `FindAliasVerbose`.
|
|
55
|
+
*
|
|
56
|
+
* `this` is the Method node, so the category searched is the Method's parent —
|
|
57
|
+
* that is what makes one handler serve every instance of
|
|
58
|
+
* `AliasNameCategoryType`, including vendor subcategories created through the
|
|
59
|
+
* `<SubAliasNameCategories>` placeholder.
|
|
60
|
+
*/
|
|
61
|
+
export declare function makeFindAliasHandler(options: FindAliasBindingOptions, verbose: boolean): (this: UAMethod, inputArguments: Variant[], context: ISessionContext) => Promise<CallMethodResultOptions>;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module node-opcua-alias-name-server
|
|
4
|
+
*
|
|
5
|
+
* The `FindAlias` (clause 6.3.2) and `FindAliasVerbose` (clause 6.3.3) Method
|
|
6
|
+
* handlers.
|
|
7
|
+
*
|
|
8
|
+
* The two Methods are identical in every respect except the DataType they
|
|
9
|
+
* return, so both are produced from one implementation: whatever the FindAlias
|
|
10
|
+
* suite proves is proved for FindAliasVerbose too.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.insertionOrderComparator = void 0;
|
|
14
|
+
exports.makeFindAliasHandler = makeFindAliasHandler;
|
|
15
|
+
const node_opcua_alias_name_common_1 = require("node-opcua-alias-name-common");
|
|
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_types_1 = require("node-opcua-types");
|
|
19
|
+
const node_opcua_variant_1 = require("node-opcua-variant");
|
|
20
|
+
/** The default: keep discovery order (a stable no-op comparator). */
|
|
21
|
+
const insertionOrderComparator = () => 0;
|
|
22
|
+
exports.insertionOrderComparator = insertionOrderComparator;
|
|
23
|
+
/** Read `AliasNameSearchPattern` (argument 0). */
|
|
24
|
+
function readPattern(inputArguments) {
|
|
25
|
+
const value = inputArguments?.[0]?.value;
|
|
26
|
+
if (value === null || value === undefined) {
|
|
27
|
+
// clause 6.3.2 gives no meaning to a null pattern; treat it as "match
|
|
28
|
+
// everything" would silently dump the whole hierarchy, so reject it
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return typeof value === "string" ? value : null;
|
|
32
|
+
}
|
|
33
|
+
/** Read `ReferenceTypeFilter` (argument 1). */
|
|
34
|
+
function readReferenceTypeFilter(inputArguments) {
|
|
35
|
+
const value = inputArguments?.[1]?.value;
|
|
36
|
+
return value instanceof node_opcua_nodeid_1.NodeId ? value : undefined;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Merge entries that share an AliasName.
|
|
40
|
+
*
|
|
41
|
+
* `AliasNameDataType` is "an array of ExpandedNodeId for a single AliasName"
|
|
42
|
+
* (clause 7.2), so the non-verbose Method reports one entry per distinct name
|
|
43
|
+
* with all of its targets. The verbose form does *not* merge: its
|
|
44
|
+
* `AliasNameCategoryId` names the category that held the alias, which differs
|
|
45
|
+
* between entries.
|
|
46
|
+
*/
|
|
47
|
+
function mergeByAliasName(entries) {
|
|
48
|
+
const byName = new Map();
|
|
49
|
+
// Membership is kept in a Set per name rather than rescanning the growing
|
|
50
|
+
// array: with a linear scan, a name shared by many entries makes this
|
|
51
|
+
// quadratic in the size of the result set.
|
|
52
|
+
const seenTargets = new Map();
|
|
53
|
+
for (const entry of entries) {
|
|
54
|
+
const existing = byName.get(entry.aliasName);
|
|
55
|
+
if (!existing) {
|
|
56
|
+
byName.set(entry.aliasName, { ...entry, referencedNodes: [...entry.referencedNodes] });
|
|
57
|
+
seenTargets.set(entry.aliasName, new Set(entry.referencedNodes.map((n) => n.toString())));
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
// written alongside byName above, so it is always present
|
|
61
|
+
const seen = seenTargets.get(entry.aliasName) ?? new Set();
|
|
62
|
+
seenTargets.set(entry.aliasName, seen);
|
|
63
|
+
for (const node of entry.referencedNodes) {
|
|
64
|
+
const key = node.toString();
|
|
65
|
+
if (!seen.has(key)) {
|
|
66
|
+
seen.add(key);
|
|
67
|
+
existing.referencedNodes.push(node);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return [...byName.values()];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Resolve each entry's AliasName namespace index, once per call.
|
|
75
|
+
*
|
|
76
|
+
* The namespace reported is the one the alias was published in, taken from the
|
|
77
|
+
* store. Using the *category's* namespace instead would put every alias on the
|
|
78
|
+
* three well-known categories into namespace 0, which is reserved for the OPC
|
|
79
|
+
* Foundation and is not what clause 6.2 intends. A store that does not know its
|
|
80
|
+
* namespace falls back to the Server's own, never to 0.
|
|
81
|
+
*
|
|
82
|
+
* Clients ignore the namespace when comparing AliasNames (clause 6.2), so this
|
|
83
|
+
* is not a matching concern — it is a matter of reporting truthfully.
|
|
84
|
+
*/
|
|
85
|
+
function makeNamespaceResolver(category) {
|
|
86
|
+
const addressSpace = category.addressSpace;
|
|
87
|
+
const ownNamespaceIndex = addressSpace.getOwnNamespace().index;
|
|
88
|
+
const cache = new Map();
|
|
89
|
+
return (entry) => {
|
|
90
|
+
if (!entry.aliasNameNamespaceUri) {
|
|
91
|
+
return ownNamespaceIndex;
|
|
92
|
+
}
|
|
93
|
+
const cached = cache.get(entry.aliasNameNamespaceUri);
|
|
94
|
+
if (cached !== undefined) {
|
|
95
|
+
return cached;
|
|
96
|
+
}
|
|
97
|
+
const index = addressSpace.getNamespaceIndex(entry.aliasNameNamespaceUri);
|
|
98
|
+
// an unregistered URI resolves to -1; reporting the Server's own
|
|
99
|
+
// namespace is closer to the truth than reporting namespace 0
|
|
100
|
+
const resolved = index >= 0 ? index : ownNamespaceIndex;
|
|
101
|
+
cache.set(entry.aliasNameNamespaceUri, resolved);
|
|
102
|
+
return resolved;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Build a handler for `FindAlias` or `FindAliasVerbose`.
|
|
107
|
+
*
|
|
108
|
+
* `this` is the Method node, so the category searched is the Method's parent —
|
|
109
|
+
* that is what makes one handler serve every instance of
|
|
110
|
+
* `AliasNameCategoryType`, including vendor subcategories created through the
|
|
111
|
+
* `<SubAliasNameCategories>` placeholder.
|
|
112
|
+
*/
|
|
113
|
+
function makeFindAliasHandler(options, verbose) {
|
|
114
|
+
const comparator = options.comparator ?? exports.insertionOrderComparator;
|
|
115
|
+
return async function findAliasHandler(inputArguments, context) {
|
|
116
|
+
const category = this.parent;
|
|
117
|
+
if (!category) {
|
|
118
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInternalError };
|
|
119
|
+
}
|
|
120
|
+
// The gate is consulted per category, and each category at most once per
|
|
121
|
+
// call. Memoised because a recursive search reaches the same category
|
|
122
|
+
// through every alias it holds, and the rule may hit a database.
|
|
123
|
+
const gate = options.isReadAllowed;
|
|
124
|
+
const decisions = new Map();
|
|
125
|
+
const mayRead = async (categoryNodeId) => {
|
|
126
|
+
if (!gate) {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
const key = categoryNodeId.toString();
|
|
130
|
+
const cached = decisions.get(key);
|
|
131
|
+
if (cached !== undefined) {
|
|
132
|
+
return cached;
|
|
133
|
+
}
|
|
134
|
+
const allowed = await gate(context, categoryNodeId);
|
|
135
|
+
decisions.set(key, allowed);
|
|
136
|
+
return allowed;
|
|
137
|
+
};
|
|
138
|
+
// A direct call on a category the caller may not read is
|
|
139
|
+
// Bad_UserAccessDenied: there is nothing left to filter, so silence
|
|
140
|
+
// would be a lie rather than a non-disclosure.
|
|
141
|
+
if (!(await mayRead(category.nodeId))) {
|
|
142
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadUserAccessDenied };
|
|
143
|
+
}
|
|
144
|
+
const pattern = readPattern(inputArguments);
|
|
145
|
+
if (pattern === null) {
|
|
146
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
|
|
147
|
+
}
|
|
148
|
+
const query = {
|
|
149
|
+
pattern,
|
|
150
|
+
referenceTypeFilter: readReferenceTypeFilter(inputArguments),
|
|
151
|
+
categoryNodeId: category.nodeId,
|
|
152
|
+
maxResults: options.maxResults,
|
|
153
|
+
// Handed the same memoised closure the filter below uses, so the
|
|
154
|
+
// rule is evaluated at most once per category per call however many
|
|
155
|
+
// times it is consulted. Passed only when a gate is configured, so
|
|
156
|
+
// an ungated Server takes exactly the path it took before.
|
|
157
|
+
isVisible: gate ? mayRead : undefined
|
|
158
|
+
};
|
|
159
|
+
let found;
|
|
160
|
+
try {
|
|
161
|
+
found = await options.store.find(query);
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
if (err instanceof node_opcua_alias_name_common_1.InvalidLikePatternError) {
|
|
165
|
+
// clause 6.3.2 Table 4: "The input string is not a valid search string"
|
|
166
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
|
|
167
|
+
}
|
|
168
|
+
throw err;
|
|
169
|
+
}
|
|
170
|
+
// clause 6.3.2 Table 4: too large to return, "try new filter and repeat find".
|
|
171
|
+
//
|
|
172
|
+
// Applied to what the store produced, *before* filtering and merging.
|
|
173
|
+
// The store stops collecting one entry past the cap, so a count that
|
|
174
|
+
// reaches it means "there may be more"; reducing the count first would
|
|
175
|
+
// report a truncated scan as a complete answer. The code names no
|
|
176
|
+
// category, so it discloses nothing a gated caller should not see.
|
|
177
|
+
if (found.length > options.maxResults) {
|
|
178
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadResponseTooLarge };
|
|
179
|
+
}
|
|
180
|
+
// A nested category the caller may not read is omitted, and the call
|
|
181
|
+
// still succeeds: an error, or a count that changed, would confirm the
|
|
182
|
+
// category exists. Absence is the only answer that discloses nothing.
|
|
183
|
+
//
|
|
184
|
+
// The store was given the same predicate and should already have skipped
|
|
185
|
+
// these, so this is normally a no-op. It stays as a backstop: an injected
|
|
186
|
+
// store written by someone else may ignore `isVisible`, and the cost of
|
|
187
|
+
// that must be a wasted scan, never a leak.
|
|
188
|
+
const visible = [];
|
|
189
|
+
for (const entry of found) {
|
|
190
|
+
if (await mayRead(entry.categoryNodeId)) {
|
|
191
|
+
visible.push(entry);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Filtering happens before the verbose/plain split, so FindAliasVerbose
|
|
195
|
+
// cannot reveal a ServerUri or an AliasNameCategoryId for a category
|
|
196
|
+
// that FindAlias would have hidden.
|
|
197
|
+
const results = verbose ? visible : mergeByAliasName(visible);
|
|
198
|
+
// sort() is stable in modern JavaScript, so a comparator that returns 0
|
|
199
|
+
// leaves discovery order untouched
|
|
200
|
+
const ordered = [...results].sort(comparator);
|
|
201
|
+
// No match is Good with an empty AliasNodeList (clause 6.3.2 Table 3),
|
|
202
|
+
// never an error.
|
|
203
|
+
const namespaceIndexOf = makeNamespaceResolver(category);
|
|
204
|
+
const value = verbose
|
|
205
|
+
? ordered.map((entry) => new node_opcua_types_1.AliasNameVerboseDataType({
|
|
206
|
+
aliasName: { name: entry.aliasName, namespaceIndex: namespaceIndexOf(entry) },
|
|
207
|
+
referencedNodes: entry.referencedNodes,
|
|
208
|
+
serverUris: entry.serverUris,
|
|
209
|
+
aliasNameCategoryId: entry.categoryNodeId
|
|
210
|
+
}))
|
|
211
|
+
: ordered.map((entry) => new node_opcua_types_1.AliasNameDataType({
|
|
212
|
+
aliasName: { name: entry.aliasName, namespaceIndex: namespaceIndexOf(entry) },
|
|
213
|
+
referencedNodes: entry.referencedNodes
|
|
214
|
+
}));
|
|
215
|
+
return {
|
|
216
|
+
statusCode: node_opcua_status_code_1.StatusCodes.Good,
|
|
217
|
+
outputArguments: [
|
|
218
|
+
{
|
|
219
|
+
dataType: node_opcua_variant_1.DataType.ExtensionObject,
|
|
220
|
+
arrayType: node_opcua_variant_1.VariantArrayType.Array,
|
|
221
|
+
value
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=bind_find_alias.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind_find_alias.js","sourceRoot":"","sources":["../source/bind_find_alias.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module node-opcua-alias-name-server
|
|
3
|
+
*
|
|
4
|
+
* Server-side OPC 10000-17 (AliasNames).
|
|
5
|
+
*
|
|
6
|
+
* Publishes **this Server's own** AliasNames. Aggregating AliasNames collected
|
|
7
|
+
* from other Servers (Annex B, Annex C) and the Annex D PubSub change
|
|
8
|
+
* notification are out of scope.
|
|
9
|
+
*/
|
|
10
|
+
export { type AddAliasOptions, AliasNameError, addAlias, findAlias, removeAlias } from "./add_alias.js";
|
|
11
|
+
export { AddressSpaceAliasStore, type AddressSpaceAliasStoreOptions } from "./address_space_alias_store.js";
|
|
12
|
+
export { aliasesOf, collectAllCategories, collectCategories, findAliasNameCategoryType, findAliasNameType, isAliasName, isAliasNameCategory, presentWellKnownCategories } from "./alias_hierarchy.js";
|
|
13
|
+
export { ALIAS_NAME_ARCHIVE_VERSION, type AliasNameArchive, readAliasNameArchive, writeAliasNameArchive } from "./alias_name_archive.js";
|
|
14
|
+
export { type AddAliasCategoryOptions, addAliasCategory, type BindAliasCategoryOptions, bindAliasCategory, ensureLastChangeProperty, ensureOptionalMethod, findMethodByDeclaration, getInstalledAliasNames, type InstalledAliasNames, removeAliasCategory } from "./bind_alias_category.js";
|
|
15
|
+
export { type AliasComparator, type FindAliasBindingOptions, insertionOrderComparator, makeFindAliasHandler } from "./bind_find_alias.js";
|
|
16
|
+
export { ALIAS_SERVER_CAPABILITY_ID, advertiseAliasCapability, type CategoryProvider, DEFAULT_MAX_RESULTS, defaultCategoryProvider, type InstallAliasNamesOptions, type InstallAliasNamesResult, type IServerForAliasNames, installAliasNames, installAliasNamesOnAddressSpace } from "./install_alias_names.js";
|
|
17
|
+
export { LAST_CHANGE_BROWSE_NAME, LastChangeTracker, type LastChangeTrackerOptions } from "./last_change.js";
|
|
18
|
+
export { ALIAS_FOR, ALIAS_NAME_CATEGORY_TYPE, ALIAS_NAME_TYPE, ALIAS_SERVER_CAPABILITY, MethodDeclarations, PUBLISHED_DATA_SET_TYPE, WellKnownCategories, WellKnownLastChange, WellKnownOptionalMethods } from "./well_known.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module node-opcua-alias-name-server
|
|
4
|
+
*
|
|
5
|
+
* Server-side OPC 10000-17 (AliasNames).
|
|
6
|
+
*
|
|
7
|
+
* Publishes **this Server's own** AliasNames. Aggregating AliasNames collected
|
|
8
|
+
* from other Servers (Annex B, Annex C) and the Annex D PubSub change
|
|
9
|
+
* notification are out of scope.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.WellKnownOptionalMethods = exports.WellKnownLastChange = exports.WellKnownCategories = exports.PUBLISHED_DATA_SET_TYPE = exports.MethodDeclarations = exports.ALIAS_SERVER_CAPABILITY = exports.ALIAS_NAME_TYPE = exports.ALIAS_NAME_CATEGORY_TYPE = exports.ALIAS_FOR = exports.LastChangeTracker = exports.LAST_CHANGE_BROWSE_NAME = exports.installAliasNamesOnAddressSpace = exports.installAliasNames = exports.defaultCategoryProvider = exports.DEFAULT_MAX_RESULTS = exports.advertiseAliasCapability = exports.ALIAS_SERVER_CAPABILITY_ID = exports.makeFindAliasHandler = exports.insertionOrderComparator = exports.removeAliasCategory = exports.getInstalledAliasNames = exports.findMethodByDeclaration = exports.ensureOptionalMethod = exports.ensureLastChangeProperty = exports.bindAliasCategory = exports.addAliasCategory = exports.writeAliasNameArchive = exports.readAliasNameArchive = exports.ALIAS_NAME_ARCHIVE_VERSION = exports.presentWellKnownCategories = exports.isAliasNameCategory = exports.isAliasName = exports.findAliasNameType = exports.findAliasNameCategoryType = exports.collectCategories = exports.collectAllCategories = exports.aliasesOf = exports.AddressSpaceAliasStore = exports.removeAlias = exports.findAlias = exports.addAlias = exports.AliasNameError = void 0;
|
|
13
|
+
var add_alias_js_1 = require("./add_alias.js");
|
|
14
|
+
Object.defineProperty(exports, "AliasNameError", { enumerable: true, get: function () { return add_alias_js_1.AliasNameError; } });
|
|
15
|
+
Object.defineProperty(exports, "addAlias", { enumerable: true, get: function () { return add_alias_js_1.addAlias; } });
|
|
16
|
+
Object.defineProperty(exports, "findAlias", { enumerable: true, get: function () { return add_alias_js_1.findAlias; } });
|
|
17
|
+
Object.defineProperty(exports, "removeAlias", { enumerable: true, get: function () { return add_alias_js_1.removeAlias; } });
|
|
18
|
+
var address_space_alias_store_js_1 = require("./address_space_alias_store.js");
|
|
19
|
+
Object.defineProperty(exports, "AddressSpaceAliasStore", { enumerable: true, get: function () { return address_space_alias_store_js_1.AddressSpaceAliasStore; } });
|
|
20
|
+
var alias_hierarchy_js_1 = require("./alias_hierarchy.js");
|
|
21
|
+
Object.defineProperty(exports, "aliasesOf", { enumerable: true, get: function () { return alias_hierarchy_js_1.aliasesOf; } });
|
|
22
|
+
Object.defineProperty(exports, "collectAllCategories", { enumerable: true, get: function () { return alias_hierarchy_js_1.collectAllCategories; } });
|
|
23
|
+
Object.defineProperty(exports, "collectCategories", { enumerable: true, get: function () { return alias_hierarchy_js_1.collectCategories; } });
|
|
24
|
+
Object.defineProperty(exports, "findAliasNameCategoryType", { enumerable: true, get: function () { return alias_hierarchy_js_1.findAliasNameCategoryType; } });
|
|
25
|
+
Object.defineProperty(exports, "findAliasNameType", { enumerable: true, get: function () { return alias_hierarchy_js_1.findAliasNameType; } });
|
|
26
|
+
Object.defineProperty(exports, "isAliasName", { enumerable: true, get: function () { return alias_hierarchy_js_1.isAliasName; } });
|
|
27
|
+
Object.defineProperty(exports, "isAliasNameCategory", { enumerable: true, get: function () { return alias_hierarchy_js_1.isAliasNameCategory; } });
|
|
28
|
+
Object.defineProperty(exports, "presentWellKnownCategories", { enumerable: true, get: function () { return alias_hierarchy_js_1.presentWellKnownCategories; } });
|
|
29
|
+
var alias_name_archive_js_1 = require("./alias_name_archive.js");
|
|
30
|
+
Object.defineProperty(exports, "ALIAS_NAME_ARCHIVE_VERSION", { enumerable: true, get: function () { return alias_name_archive_js_1.ALIAS_NAME_ARCHIVE_VERSION; } });
|
|
31
|
+
Object.defineProperty(exports, "readAliasNameArchive", { enumerable: true, get: function () { return alias_name_archive_js_1.readAliasNameArchive; } });
|
|
32
|
+
Object.defineProperty(exports, "writeAliasNameArchive", { enumerable: true, get: function () { return alias_name_archive_js_1.writeAliasNameArchive; } });
|
|
33
|
+
var bind_alias_category_js_1 = require("./bind_alias_category.js");
|
|
34
|
+
Object.defineProperty(exports, "addAliasCategory", { enumerable: true, get: function () { return bind_alias_category_js_1.addAliasCategory; } });
|
|
35
|
+
Object.defineProperty(exports, "bindAliasCategory", { enumerable: true, get: function () { return bind_alias_category_js_1.bindAliasCategory; } });
|
|
36
|
+
Object.defineProperty(exports, "ensureLastChangeProperty", { enumerable: true, get: function () { return bind_alias_category_js_1.ensureLastChangeProperty; } });
|
|
37
|
+
Object.defineProperty(exports, "ensureOptionalMethod", { enumerable: true, get: function () { return bind_alias_category_js_1.ensureOptionalMethod; } });
|
|
38
|
+
Object.defineProperty(exports, "findMethodByDeclaration", { enumerable: true, get: function () { return bind_alias_category_js_1.findMethodByDeclaration; } });
|
|
39
|
+
Object.defineProperty(exports, "getInstalledAliasNames", { enumerable: true, get: function () { return bind_alias_category_js_1.getInstalledAliasNames; } });
|
|
40
|
+
Object.defineProperty(exports, "removeAliasCategory", { enumerable: true, get: function () { return bind_alias_category_js_1.removeAliasCategory; } });
|
|
41
|
+
var bind_find_alias_js_1 = require("./bind_find_alias.js");
|
|
42
|
+
Object.defineProperty(exports, "insertionOrderComparator", { enumerable: true, get: function () { return bind_find_alias_js_1.insertionOrderComparator; } });
|
|
43
|
+
Object.defineProperty(exports, "makeFindAliasHandler", { enumerable: true, get: function () { return bind_find_alias_js_1.makeFindAliasHandler; } });
|
|
44
|
+
var install_alias_names_js_1 = require("./install_alias_names.js");
|
|
45
|
+
Object.defineProperty(exports, "ALIAS_SERVER_CAPABILITY_ID", { enumerable: true, get: function () { return install_alias_names_js_1.ALIAS_SERVER_CAPABILITY_ID; } });
|
|
46
|
+
Object.defineProperty(exports, "advertiseAliasCapability", { enumerable: true, get: function () { return install_alias_names_js_1.advertiseAliasCapability; } });
|
|
47
|
+
Object.defineProperty(exports, "DEFAULT_MAX_RESULTS", { enumerable: true, get: function () { return install_alias_names_js_1.DEFAULT_MAX_RESULTS; } });
|
|
48
|
+
Object.defineProperty(exports, "defaultCategoryProvider", { enumerable: true, get: function () { return install_alias_names_js_1.defaultCategoryProvider; } });
|
|
49
|
+
Object.defineProperty(exports, "installAliasNames", { enumerable: true, get: function () { return install_alias_names_js_1.installAliasNames; } });
|
|
50
|
+
Object.defineProperty(exports, "installAliasNamesOnAddressSpace", { enumerable: true, get: function () { return install_alias_names_js_1.installAliasNamesOnAddressSpace; } });
|
|
51
|
+
var last_change_js_1 = require("./last_change.js");
|
|
52
|
+
Object.defineProperty(exports, "LAST_CHANGE_BROWSE_NAME", { enumerable: true, get: function () { return last_change_js_1.LAST_CHANGE_BROWSE_NAME; } });
|
|
53
|
+
Object.defineProperty(exports, "LastChangeTracker", { enumerable: true, get: function () { return last_change_js_1.LastChangeTracker; } });
|
|
54
|
+
var well_known_js_1 = require("./well_known.js");
|
|
55
|
+
Object.defineProperty(exports, "ALIAS_FOR", { enumerable: true, get: function () { return well_known_js_1.ALIAS_FOR; } });
|
|
56
|
+
Object.defineProperty(exports, "ALIAS_NAME_CATEGORY_TYPE", { enumerable: true, get: function () { return well_known_js_1.ALIAS_NAME_CATEGORY_TYPE; } });
|
|
57
|
+
Object.defineProperty(exports, "ALIAS_NAME_TYPE", { enumerable: true, get: function () { return well_known_js_1.ALIAS_NAME_TYPE; } });
|
|
58
|
+
Object.defineProperty(exports, "ALIAS_SERVER_CAPABILITY", { enumerable: true, get: function () { return well_known_js_1.ALIAS_SERVER_CAPABILITY; } });
|
|
59
|
+
Object.defineProperty(exports, "MethodDeclarations", { enumerable: true, get: function () { return well_known_js_1.MethodDeclarations; } });
|
|
60
|
+
Object.defineProperty(exports, "PUBLISHED_DATA_SET_TYPE", { enumerable: true, get: function () { return well_known_js_1.PUBLISHED_DATA_SET_TYPE; } });
|
|
61
|
+
Object.defineProperty(exports, "WellKnownCategories", { enumerable: true, get: function () { return well_known_js_1.WellKnownCategories; } });
|
|
62
|
+
Object.defineProperty(exports, "WellKnownLastChange", { enumerable: true, get: function () { return well_known_js_1.WellKnownLastChange; } });
|
|
63
|
+
Object.defineProperty(exports, "WellKnownOptionalMethods", { enumerable: true, get: function () { return well_known_js_1.WellKnownOptionalMethods; } });
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH,+CAAwG;AAAzE,8GAAA,cAAc,OAAA;AAAE,wGAAA,QAAQ,OAAA;AAAE,yGAAA,SAAS,OAAA;AAAE,2GAAA,WAAW,OAAA;AAC/E,+EAA4G;AAAnG,sIAAA,sBAAsB,OAAA;AAC/B,2DAS8B;AAR1B,+GAAA,SAAS,OAAA;AACT,0HAAA,oBAAoB,OAAA;AACpB,uHAAA,iBAAiB,OAAA;AACjB,+HAAA,yBAAyB,OAAA;AACzB,uHAAA,iBAAiB,OAAA;AACjB,iHAAA,WAAW,OAAA;AACX,yHAAA,mBAAmB,OAAA;AACnB,gIAAA,0BAA0B,OAAA;AAE9B,iEAKiC;AAJ7B,mIAAA,0BAA0B,OAAA;AAE1B,6HAAA,oBAAoB,OAAA;AACpB,8HAAA,qBAAqB,OAAA;AAEzB,mEAWkC;AAT9B,0HAAA,gBAAgB,OAAA;AAEhB,2HAAA,iBAAiB,OAAA;AACjB,kIAAA,wBAAwB,OAAA;AACxB,8HAAA,oBAAoB,OAAA;AACpB,iIAAA,uBAAuB,OAAA;AACvB,gIAAA,sBAAsB,OAAA;AAEtB,6HAAA,mBAAmB,OAAA;AAEvB,2DAK8B;AAF1B,8HAAA,wBAAwB,OAAA;AACxB,0HAAA,oBAAoB,OAAA;AAExB,mEAWkC;AAV9B,oIAAA,0BAA0B,OAAA;AAC1B,kIAAA,wBAAwB,OAAA;AAExB,6HAAA,mBAAmB,OAAA;AACnB,iIAAA,uBAAuB,OAAA;AAIvB,2HAAA,iBAAiB,OAAA;AACjB,yIAAA,+BAA+B,OAAA;AAEnC,mDAI0B;AAHtB,yHAAA,uBAAuB,OAAA;AACvB,mHAAA,iBAAiB,OAAA;AAGrB,iDAUyB;AATrB,0GAAA,SAAS,OAAA;AACT,yHAAA,wBAAwB,OAAA;AACxB,gHAAA,eAAe,OAAA;AACf,wHAAA,uBAAuB,OAAA;AACvB,mHAAA,kBAAkB,OAAA;AAClB,wHAAA,uBAAuB,OAAA;AACvB,oHAAA,mBAAmB,OAAA;AACnB,oHAAA,mBAAmB,OAAA;AACnB,yHAAA,wBAAwB,OAAA"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module node-opcua-alias-name-server
|
|
3
|
+
*
|
|
4
|
+
* Install OPC 10000-17 AliasName support on a Server.
|
|
5
|
+
*
|
|
6
|
+
* Every node-opcua Server that loads the standard nodeset already exposes
|
|
7
|
+
* `Aliases`, `TagVariables` and `Topics`, each carrying a MANDATORY `FindAlias`
|
|
8
|
+
* Method that is bound to nothing. A conformance tester therefore sees the SDK
|
|
9
|
+
* advertise the AliasName feature and then fail its only required Method. This
|
|
10
|
+
* binds them.
|
|
11
|
+
*/
|
|
12
|
+
import type { IAddressSpace, ISessionContext, UAObject } from "node-opcua-address-space-base";
|
|
13
|
+
import type { IAliasStore, LikeOptions } from "node-opcua-alias-name-common";
|
|
14
|
+
import type { NodeId } from "node-opcua-nodeid";
|
|
15
|
+
import { type BindAliasCategoryOptions } from "./bind_alias_category.js";
|
|
16
|
+
import type { AliasComparator } from "./bind_find_alias.js";
|
|
17
|
+
import { LastChangeTracker } from "./last_change.js";
|
|
18
|
+
import { DEFAULT_MAX_RESULTS } from "./well_known.js";
|
|
19
|
+
export { DEFAULT_MAX_RESULTS };
|
|
20
|
+
/**
|
|
21
|
+
* Supplies the `AliasNameCategoryType` instances to bind.
|
|
22
|
+
*
|
|
23
|
+
* Defaults to {@link defaultCategoryProvider}, which walks down from `Aliases`.
|
|
24
|
+
* Replace it when the category set is not a static tree — one category per
|
|
25
|
+
* customer, one per upstream Server, categories that appear and disappear at
|
|
26
|
+
* runtime. May be asynchronous, since the set may have to be fetched.
|
|
27
|
+
*
|
|
28
|
+
* A provider only decides *what installation binds*. Categories created after
|
|
29
|
+
* installation are bound with {@link bindAliasCategory}, or created already
|
|
30
|
+
* bound with {@link addAliasCategory}.
|
|
31
|
+
*/
|
|
32
|
+
export type CategoryProvider = (addressSpace: IAddressSpace) => UAObject[] | Promise<UAObject[]>;
|
|
33
|
+
/**
|
|
34
|
+
* The default provider: every `AliasNameCategoryType` instance at or below
|
|
35
|
+
* `Aliases`, plus any roots named in `additionalCategoryRoots`.
|
|
36
|
+
*
|
|
37
|
+
* `additionalCategoryRoots` is expressed through this rather than as a parallel
|
|
38
|
+
* mechanism, so a custom provider can reuse it — `defaultCategoryProvider(roots)`
|
|
39
|
+
* composes with whatever else the Server knows about.
|
|
40
|
+
*/
|
|
41
|
+
export declare function defaultCategoryProvider(additionalRoots?: Array<NodeId | UAObject>): CategoryProvider;
|
|
42
|
+
export interface InstallAliasNamesOptions {
|
|
43
|
+
/**
|
|
44
|
+
* Where aliases come from. Defaults to an {@link AddressSpaceAliasStore},
|
|
45
|
+
* which reads them straight out of the address space — so a Server whose
|
|
46
|
+
* NodeSet2.xml already models `AliasNameType` instances needs no options at
|
|
47
|
+
* all.
|
|
48
|
+
*/
|
|
49
|
+
store?: IAliasStore;
|
|
50
|
+
/** Result cap per call (clause 6.3.2 Table 4). Defaults to {@link DEFAULT_MAX_RESULTS}. */
|
|
51
|
+
maxResults?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Also bind `FindAliasVerbose` (clause 6.3.3, conformance unit
|
|
54
|
+
* AliasName FindAliasVerbose). On by default: it costs one extra Method per
|
|
55
|
+
* category and is what lets a Client see which category held a hit.
|
|
56
|
+
*/
|
|
57
|
+
verbose?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Also expose `AddAliasesToCategory` and `DeleteAliasesFromCategory`
|
|
60
|
+
* (clauses 6.3.4 and 6.3.5, conformance unit *AliasName Configuration
|
|
61
|
+
* Support*, CU 5874).
|
|
62
|
+
*
|
|
63
|
+
* **Off by default**: both Methods are Optional, and a write surface that
|
|
64
|
+
* appears without being asked for is a surface nobody reviewed. Turning it
|
|
65
|
+
* on is not by itself dangerous — every call is denied until
|
|
66
|
+
* {@link isWriteAllowed} says otherwise — but the Methods do become visible
|
|
67
|
+
* to a browsing Client.
|
|
68
|
+
*/
|
|
69
|
+
configurationMethods?: boolean;
|
|
70
|
+
/** Passed to the `Like` matcher used by the default store. */
|
|
71
|
+
likeOptions?: LikeOptions;
|
|
72
|
+
/** Result ordering (clause 6.3.2, "best match first"). */
|
|
73
|
+
comparator?: AliasComparator;
|
|
74
|
+
/**
|
|
75
|
+
* Read gate, consulted **per category** and allowed to be asynchronous.
|
|
76
|
+
* Defaults to allowing everyone, so a Server that simply publishes its
|
|
77
|
+
* aliases is unaffected.
|
|
78
|
+
*
|
|
79
|
+
* A direct call on a denied category answers `Bad_UserAccessDenied`; a
|
|
80
|
+
* denied category reached by a recursive search is omitted and the call
|
|
81
|
+
* still returns `Good`, so nothing reveals that it exists.
|
|
82
|
+
*
|
|
83
|
+
* OPC 10000-17 defines no security model — four `Bad_UserAccessDenied` rows,
|
|
84
|
+
* no Security clause, no Roles, and no `RolePermissions` on any Part 17 node
|
|
85
|
+
* in the standard nodeset — so every Server has to supply its own rule.
|
|
86
|
+
*/
|
|
87
|
+
isReadAllowed?: (context: ISessionContext, categoryNodeId: NodeId) => boolean | Promise<boolean>;
|
|
88
|
+
/**
|
|
89
|
+
* Write gate for the configuration Methods, mirroring
|
|
90
|
+
* {@link isReadAllowed}. **Defaults to denying everyone**: the write surface
|
|
91
|
+
* is the one place where a permissive default would be a security defect
|
|
92
|
+
* rather than a convenience.
|
|
93
|
+
*/
|
|
94
|
+
isWriteAllowed?: (context: ISessionContext, categoryNodeId: NodeId) => boolean | Promise<boolean>;
|
|
95
|
+
/**
|
|
96
|
+
* File backing the persisted `LastChange` values (clause 6.3.1: *"The
|
|
97
|
+
* LastChange shall be persisted"*).
|
|
98
|
+
*
|
|
99
|
+
* Without it, every restart resets `LastChange` to zero — and a Client that
|
|
100
|
+
* sees a value older than the one it cached is required by clause 6.3.1 to
|
|
101
|
+
* clear its cache. So an unpersisted Server silently orders every connected
|
|
102
|
+
* Client to discard a still-valid cache on every restart. Set this on any
|
|
103
|
+
* Server that Clients cache against.
|
|
104
|
+
*
|
|
105
|
+
* The file is small JSON: a version and a map of category NodeId to
|
|
106
|
+
* VersionTime. Writes are atomic.
|
|
107
|
+
*/
|
|
108
|
+
persistencePath?: string;
|
|
109
|
+
/**
|
|
110
|
+
* Add a `LastChange` Property to every category, not only the `Aliases` root.
|
|
111
|
+
*
|
|
112
|
+
* On by default. `LastChange` is Optional on `AliasNameCategoryType` and the
|
|
113
|
+
* shipped nodeset instantiates it only on the root, which clause 9.2 makes
|
|
114
|
+
* mandatory — but the clause 6.3.1 rollup is only observable where the
|
|
115
|
+
* Property exists, so a Client watching one branch needs it there. Turn it
|
|
116
|
+
* off to keep the address space exactly as the nodeset ships it.
|
|
117
|
+
*/
|
|
118
|
+
lastChangeOnAllCategories?: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Supplies "now" as a VersionTime, for tests that need to pin it. A
|
|
121
|
+
* VersionTime has one-second resolution, which is otherwise awkward to
|
|
122
|
+
* assert against.
|
|
123
|
+
*/
|
|
124
|
+
nowVersionTime?: () => number;
|
|
125
|
+
/**
|
|
126
|
+
* Extra roots to search for `AliasNameCategoryType` instances.
|
|
127
|
+
*
|
|
128
|
+
* Categories are discovered by walking down from `Aliases`, which is where
|
|
129
|
+
* clause 9.1 puts them. Name a category here if the Server models one
|
|
130
|
+
* outside that hierarchy, otherwise its MANDATORY `FindAlias` stays unbound.
|
|
131
|
+
*
|
|
132
|
+
* Ignored when {@link categoryProvider} is supplied — compose it in with
|
|
133
|
+
* {@link defaultCategoryProvider} instead of passing both.
|
|
134
|
+
*/
|
|
135
|
+
additionalCategoryRoots?: Array<NodeId | UAObject>;
|
|
136
|
+
/**
|
|
137
|
+
* Replace category discovery entirely. See {@link CategoryProvider}.
|
|
138
|
+
*/
|
|
139
|
+
categoryProvider?: CategoryProvider;
|
|
140
|
+
/**
|
|
141
|
+
* Declare the `ALIAS` ServerCapability (OPC 10000-12 Annex D Table D.1).
|
|
142
|
+
* **On by default.**
|
|
143
|
+
*
|
|
144
|
+
* A Server that does not advertise it is never discovered by anything
|
|
145
|
+
* looking for alias-capable Servers, and nothing reports the failure — so
|
|
146
|
+
* leaving it to each caller to remember means it will sometimes be
|
|
147
|
+
* forgotten, invisibly. Installing the feature and declaring it are the same
|
|
148
|
+
* decision, so they happen together.
|
|
149
|
+
*
|
|
150
|
+
* **Call `installAliasNames` before `server.start()`.** The address space
|
|
151
|
+
* exists from `initialize()` onwards, and mDNS/LDS registration reads the
|
|
152
|
+
* capability list during `start()` — afterwards the list is still correct
|
|
153
|
+
* for anything reading `ServerConfiguration`, but the registration has
|
|
154
|
+
* already gone out without it.
|
|
155
|
+
*
|
|
156
|
+
* Set false if the Server manages its own capability list.
|
|
157
|
+
*/
|
|
158
|
+
advertiseCapability?: boolean;
|
|
159
|
+
}
|
|
160
|
+
export interface InstallAliasNamesResult {
|
|
161
|
+
/** The store that was used — the injected one, or the default. */
|
|
162
|
+
store: IAliasStore;
|
|
163
|
+
/** Every `AliasNameCategoryType` instance that had its Methods bound. */
|
|
164
|
+
categories: NodeId[];
|
|
165
|
+
/** True when this call did the work; false when AliasNames were already installed. */
|
|
166
|
+
installed: boolean;
|
|
167
|
+
/**
|
|
168
|
+
* Keeps `LastChange` correct across the hierarchy, and persists it
|
|
169
|
+
* (clause 6.3.1).
|
|
170
|
+
*/
|
|
171
|
+
lastChange?: LastChangeTracker;
|
|
172
|
+
/**
|
|
173
|
+
* The options every category was bound with.
|
|
174
|
+
*
|
|
175
|
+
* Pass these to {@link bindAliasCategory} to bind a category created later
|
|
176
|
+
* exactly as the installed ones were bound, without reassembling them by
|
|
177
|
+
* hand and risking a different store or result cap.
|
|
178
|
+
*/
|
|
179
|
+
bindingOptions: BindAliasCategoryOptions;
|
|
180
|
+
}
|
|
181
|
+
/** The server-like object we need: the address space, and the capability list. */
|
|
182
|
+
export interface IServerForAliasNames {
|
|
183
|
+
engine: {
|
|
184
|
+
addressSpace: IAddressSpace | null;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* The Server's OPC 10000-12 Annex D capability identifiers — on an
|
|
188
|
+
* `OPCUAServer` this is `capabilitiesForMDNS`. Optional so a caller can pass
|
|
189
|
+
* anything address-space-shaped; when present, `ALIAS` is added to it.
|
|
190
|
+
*/
|
|
191
|
+
capabilitiesForMDNS?: string[];
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* The `ALIAS` ServerCapability identifier (OPC 10000-12 Annex D Table D.1).
|
|
195
|
+
*
|
|
196
|
+
* Part 17's prose writes it `Alias`; Part 12 Annex D is the normative source and
|
|
197
|
+
* writes `ALIAS`, matched case-insensitively.
|
|
198
|
+
*/
|
|
199
|
+
export declare const ALIAS_SERVER_CAPABILITY_ID = "ALIAS";
|
|
200
|
+
/**
|
|
201
|
+
* Add `ALIAS` to a Server's Annex D capability list, in place.
|
|
202
|
+
*
|
|
203
|
+
* Idempotent, case-insensitive, and replaces the `NA` placeholder rather than
|
|
204
|
+
* producing the meaningless `["NA", "ALIAS"]`.
|
|
205
|
+
*
|
|
206
|
+
* @returns true when the list was changed.
|
|
207
|
+
*/
|
|
208
|
+
export declare function advertiseAliasCapability(capabilities: string[]): boolean;
|
|
209
|
+
/**
|
|
210
|
+
* Install AliasName support on a Server.
|
|
211
|
+
*
|
|
212
|
+
* Call it **between `initialize()` and `start()`**: the address space exists
|
|
213
|
+
* from `initialize()`, and the `ALIAS` capability has to be in place before
|
|
214
|
+
* `start()` performs the mDNS/LDS registration that reads it.
|
|
215
|
+
*
|
|
216
|
+
* ```ts
|
|
217
|
+
* await server.initialize();
|
|
218
|
+
* await installAliasNames(server);
|
|
219
|
+
* await server.start();
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
export declare function installAliasNames(server: IServerForAliasNames, options?: InstallAliasNamesOptions): Promise<InstallAliasNamesResult>;
|
|
223
|
+
/**
|
|
224
|
+
* Install AliasName support directly on an address space.
|
|
225
|
+
*
|
|
226
|
+
* The two-tier form used elsewhere in the SDK: this one needs no Server, so it
|
|
227
|
+
* can be driven from a test or from a tool that only has an address space.
|
|
228
|
+
*/
|
|
229
|
+
export declare function installAliasNamesOnAddressSpace(addressSpace: IAddressSpace, options?: InstallAliasNamesOptions): Promise<InstallAliasNamesResult>;
|