• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

node-opcua / node-opcua / 22636309940

03 Mar 2026 06:03PM UTC coverage: 92.756% (+1.9%) from 90.81%
22636309940

push

github

erossignon
test: disable ENOENT on overlapping trustCertificate invocations in test environments with concurrency tests

18684 of 22141 branches covered (84.39%)

23 of 37 new or added lines in 1 file covered. (62.16%)

5775 existing lines in 228 files now uncovered.

160668 of 173216 relevant lines covered (92.76%)

875869.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.56
/packages/node-opcua-pseudo-session/source/basic_session_interface.ts
1
/**
2✔
2
 * @module node-opcua-pseudo-session
2✔
3
 */
2✔
4
import { assert } from "node-opcua-assert";
2✔
5
import { ByteString } from "node-opcua-basic-types";
2✔
6
import { AttributeIds, BrowseDirection, makeResultMask } from "node-opcua-data-model";
2✔
7
import { DataValue } from "node-opcua-data-value";
2✔
8
import { NodeIdLike, resolveNodeId } from "node-opcua-nodeid";
2✔
9
import { BrowseDescription, BrowseDescriptionOptions, BrowseResult } from "node-opcua-service-browse";
2✔
10
import { Argument, CallMethodRequestOptions, CallMethodResult } from "node-opcua-service-call";
2✔
11
import { ReadValueIdOptions } from "node-opcua-service-read";
2✔
12
import { WriteValueOptions } from "node-opcua-service-write";
2✔
13
import { BrowsePath, BrowsePathResult } from "node-opcua-service-translate-browse-path";
2✔
14
import { DataType, VariantArrayType } from "node-opcua-variant";
2✔
15
import { CallbackT, StatusCode, StatusCodes } from "node-opcua-status-code";
2✔
16
import { VariableIds } from "node-opcua-constants";
2✔
17
import { BrowsePathOptions, UserTokenType, X509IdentityTokenOptions } from "node-opcua-types";
2✔
18

2✔
19
export type BrowseDescriptionLike = string | BrowseDescriptionOptions;
2✔
20
export type CallMethodRequestLike = CallMethodRequestOptions;
2✔
21

2✔
22
export type ResponseCallback<T> = (err: Error | null, result?: T) => void;
2✔
23

2✔
24
export type MethodId = NodeIdLike;
2✔
25

2✔
26
export interface ArgumentDefinition {
2✔
27
    inputArguments: Argument[];
2✔
28
    outputArguments: Argument[];
2✔
29
}
2✔
30
export interface IBasicTransportSettings {
2✔
31
    maxMessageSize: number;
2✔
32
}
2✔
33

2✔
34
// #region Browse
2✔
35
export interface IBasicSessionBrowseAsyncSimple {
2✔
36
    browse(nodeToBrowse: BrowseDescriptionLike): Promise<BrowseResult>;
2✔
37
}
2✔
38

2✔
39
export interface IBasicSessionBrowseAsyncMultiple {
2✔
40
    browse(nodesToBrowse: BrowseDescriptionLike[]): Promise<BrowseResult[]>;
2✔
41
}
2✔
42
export interface IBasicSessionBrowseAsync extends IBasicSessionBrowseAsyncSimple, IBasicSessionBrowseAsyncMultiple {
2✔
43
    browse(nodeToBrowse: BrowseDescriptionLike): Promise<BrowseResult>;
2✔
44
    browse(nodesToBrowse: BrowseDescriptionLike[]): Promise<BrowseResult[]>;
2✔
45
}
2✔
46

2✔
47
export interface IBasicSessionBrowseCallback {
2✔
48
    browse(nodeToBrowse: BrowseDescriptionLike, callback: ResponseCallback<BrowseResult>): void;
2✔
49

2✔
50
    browse(nodesToBrowse: BrowseDescriptionLike[], callback: ResponseCallback<BrowseResult[]>): void;
2✔
51
}
2✔
52
export interface IBasicSessionBrowse extends IBasicSessionBrowseAsync, IBasicSessionBrowseCallback {
2✔
53
    browse(nodeToBrowse: BrowseDescriptionLike): Promise<BrowseResult>;
2✔
54
    browse(nodesToBrowse: BrowseDescriptionLike[]): Promise<BrowseResult[]>;
2✔
55
    browse(nodeToBrowse: BrowseDescriptionLike, callback: ResponseCallback<BrowseResult>): void;
2✔
56

2✔
57
    browse(nodesToBrowse: BrowseDescriptionLike[], callback: ResponseCallback<BrowseResult[]>): void;
2✔
58
}
2✔
59
// #endregion
2✔
60

2✔
61
// #region BrowseNext
2✔
62
export interface IBasicSessionBrowseNextAsyncSimple {
2✔
63
    browseNext(continuationPoint: Buffer, releaseContinuationPoints: boolean): Promise<BrowseResult>;
2✔
64
}
2✔
65
export interface IBasicSessionBrowseNextAsyncMultiple {
2✔
66
    browseNext(continuationPoints: Buffer[], releaseContinuationPoints: boolean): Promise<BrowseResult[]>;
2✔
67
}
2✔
68
export interface IBasicSessionBrowseNextAsync extends IBasicSessionBrowseNextAsyncMultiple, IBasicSessionBrowseNextAsyncSimple {
2✔
69
    browseNext(continuationPoint: Buffer, releaseContinuationPoints: boolean): Promise<BrowseResult>;
2✔
70
    browseNext(continuationPoints: Buffer[], releaseContinuationPoints: boolean): Promise<BrowseResult[]>;
2✔
71
}
2✔
72
export interface IBasicSessionBrowseNextCallback {
2✔
73
    /**
2✔
74
     *
2✔
75
     * @param continuationPoint
2✔
76
     * @param releaseContinuationPoints  a Boolean parameter with the following values:
2✔
77
     *     * `true` passed continuationPoints shall be reset to free resources in
2✔
78
     *      the Server. The continuation points are released and the results
2✔
79
     *      and diagnosticInfos arrays are empty.
2✔
80
     *     * `false` passed continuationPoints shall be used to get the next set of
2✔
81
     *      browse information.
2✔
82
     *
2✔
83
     *   A Client shall always use the continuation point returned by a Browse or
2✔
84
     *    BrowseNext response to free the resources for the continuation point in the
2✔
85
     *    Server. If the Client does not want to get the next set of browse information,
2✔
86
     *    BrowseNext shall be called with this parameter set to `true`.
2✔
87
     *
2✔
88
     */
2✔
89
    browseNext(continuationPoint: Buffer, releaseContinuationPoints: boolean, callback: ResponseCallback<BrowseResult>): void;
2✔
90

2✔
91
    browseNext(continuationPoints: Buffer[], releaseContinuationPoints: boolean, callback: ResponseCallback<BrowseResult[]>): void;
2✔
92
}
2✔
93
export interface IBasicSessionBrowseNext extends IBasicSessionBrowseNextAsync, IBasicSessionBrowseNextCallback {
2✔
94
    browseNext(continuationPoint: Buffer, releaseContinuationPoints: boolean): Promise<BrowseResult>;
2✔
95
    browseNext(continuationPoints: Buffer[], releaseContinuationPoints: boolean): Promise<BrowseResult[]>;
2✔
96
    browseNext(continuationPoint: Buffer, releaseContinuationPoints: boolean, callback: ResponseCallback<BrowseResult>): void;
2✔
97

2✔
98
    browseNext(continuationPoints: Buffer[], releaseContinuationPoints: boolean, callback: ResponseCallback<BrowseResult[]>): void;
2✔
99
}
2✔
100
// #endregion
2✔
101

2✔
102
// #region Read
2✔
103
export interface IBasicSessionReadAsyncSimple {
2✔
104
    read(nodeToRead: ReadValueIdOptions, maxAge?: number): Promise<DataValue>;
2✔
105
}
2✔
106
export interface IBasicSessionReadAsyncMultiple {
2✔
107
    read(nodesToRead: ReadValueIdOptions[], maxAge?: number): Promise<DataValue[]>;
2✔
108
}
2✔
109

2✔
110
export interface IBasicSessionReadAsync extends IBasicSessionReadAsyncSimple, IBasicSessionReadAsyncMultiple {
2✔
111
    read(nodeToRead: ReadValueIdOptions, maxAge?: number): Promise<DataValue>;
2✔
112
    read(nodesToRead: ReadValueIdOptions[], maxAge?: number): Promise<DataValue[]>;
2✔
113
}
2✔
114
export interface IBasicSessionReadCallback {
2✔
115
    read(nodeToRead: ReadValueIdOptions, maxAge: number, callback: ResponseCallback<DataValue>): void;
2✔
116
    read(nodesToRead: ReadValueIdOptions[], maxAge: number, callback: ResponseCallback<DataValue[]>): void;
2✔
117
    read(nodeToRead: ReadValueIdOptions, callback: ResponseCallback<DataValue>): void;
2✔
118
    read(nodesToRead: ReadValueIdOptions[], callback: ResponseCallback<DataValue[]>): void;
2✔
119
}
2✔
120
export interface IBasicSessionRead extends IBasicSessionReadCallback, IBasicSessionReadAsync {
2✔
121
    read(nodeToRead: ReadValueIdOptions, maxAge?: number): Promise<DataValue>;
2✔
122
    read(nodesToRead: ReadValueIdOptions[], maxAge?: number): Promise<DataValue[]>;
2✔
123
    read(nodeToRead: ReadValueIdOptions, maxAge: number, callback: ResponseCallback<DataValue>): void;
2✔
124
    read(nodesToRead: ReadValueIdOptions[], maxAge: number, callback: ResponseCallback<DataValue[]>): void;
2✔
125
    read(nodeToRead: ReadValueIdOptions, callback: ResponseCallback<DataValue>): void;
2✔
126
    read(nodesToRead: ReadValueIdOptions[], callback: ResponseCallback<DataValue[]>): void;
2✔
127
}
2✔
128
// #endregion
2✔
129

2✔
130
// #region Write
2✔
131
export interface IBasicSessionWriteAsyncSimple {
2✔
132
    write(nodeToWrite: WriteValueOptions): Promise<StatusCode>;
2✔
133
}
2✔
134
export interface IBasicSessionWriteAsyncMultiple {
2✔
135
    write(nodesToWrite: WriteValueOptions[]): Promise<StatusCode[]>;
2✔
136
}
2✔
137
export interface IBasicSessionWriteAsync extends IBasicSessionWriteAsyncSimple, IBasicSessionWriteAsyncMultiple {
2✔
138
    write(nodeToWrite: WriteValueOptions): Promise<StatusCode>;
2✔
139
    write(nodesToWrite: WriteValueOptions[]): Promise<StatusCode[]>;
2✔
140
}
2✔
141
export interface IBasicSessionWriteCallback {
2✔
142
    write(nodeToWrite: WriteValueOptions, callback: ResponseCallback<StatusCode>): void;
2✔
143
    write(nodesToWrite: WriteValueOptions[], callback: ResponseCallback<StatusCode[]>): void;
2✔
144
}
2✔
145
export interface IBasicSessionWrite extends IBasicSessionWriteCallback, IBasicSessionWriteAsync {
2✔
146
    write(nodeToWrite: WriteValueOptions): Promise<StatusCode>;
2✔
147
    write(nodesToWrite: WriteValueOptions[]): Promise<StatusCode[]>;
2✔
148
    write(nodeToWrite: WriteValueOptions, callback: ResponseCallback<StatusCode>): void;
2✔
149
    write(nodesToWrite: WriteValueOptions[], callback: ResponseCallback<StatusCode[]>): void;
2✔
150
}
2✔
151

2✔
152
// #endregion
2✔
153

2✔
154
// #region Call
2✔
155
export interface IBasicSessionCallAsyncSimple {
2✔
156
    call(methodToCall: CallMethodRequestLike): Promise<CallMethodResult>;
2✔
157
}
2✔
158
export interface IBasicSessionCallAsyncMultiple {
2✔
159
    call(methodsToCall: CallMethodRequestLike[]): Promise<CallMethodResult[]>;
2✔
160
}
2✔
161
export interface IBasicSessionCallAsync extends IBasicSessionCallAsyncSimple, IBasicSessionCallAsyncMultiple {
2✔
162
    call(methodToCall: CallMethodRequestLike): Promise<CallMethodResult>;
2✔
163
    call(methodsToCall: CallMethodRequestLike[]): Promise<CallMethodResult[]>;
2✔
164
}
2✔
165
export interface IBasicSessionCallCallback {
2✔
166
    call(methodToCall: CallMethodRequestLike, callback: (err: Error | null, result?: CallMethodResult) => void): void;
2✔
167
    call(methodsToCall: CallMethodRequestLike[], callback: (err: Error | null, results?: CallMethodResult[]) => void): void;
2✔
168
}
2✔
169

2✔
170
export interface IBasicSessionCall extends IBasicSessionCallCallback, IBasicSessionCallAsync {
2✔
171
    /**
2✔
172
     *
2✔
173
     *
2✔
174
     * @param methodToCall {CallMethodRequest} the call method request
2✔
175
     * @param callback
2✔
176
     *
2✔
177
     * @example :
2✔
178
     *
2✔
179
     * ```javascript
2✔
180
     * const methodToCall = {
2✔
181
     *     objectId: "ns=2;i=12",
2✔
182
     *     methodId: "ns=2;i=13",
2✔
183
     *     inputArguments: [
2✔
184
     *         new Variant({...}),
2✔
185
     *         new Variant({...}),
2✔
186
     *     ]
2✔
187
     * }
2✔
188
     * session.call(methodToCall,function(err,callResult) {
2✔
189
     *    if (!err) {
2✔
190
     *         console.log(" statusCode = ",callResult.statusCode);
2✔
191
     *         console.log(" inputArgumentResults[0] = ",callResult.inputArgumentResults[0].toString());
2✔
192
     *         console.log(" inputArgumentResults[1] = ",callResult.inputArgumentResults[1].toString());
2✔
193
     *         console.log(" outputArgument[0]       = ",callResult.outputArgument[0].toString()); // array of variant
2✔
194
     *    }
2✔
195
     * });
2✔
196
     * ```
2✔
197
     *
2✔
198
     *
2✔
199
     * @param methodsToCall {CallMethodRequest[]} the call method request array
2✔
200
     * @param callback
2✔
201
     *
2✔
202
     *
2✔
203
     * @example :
2✔
204
     *
2✔
205
     * ```javascript
2✔
206
     * const methodsToCall = [ {
2✔
207
     *     objectId: "ns=2;i=12",
2✔
208
     *     methodId: "ns=2;i=13",
2✔
209
     *     inputArguments: [
2✔
210
     *         new Variant({...}),
2✔
211
     *         new Variant({...}),
2✔
212
     *     ]
2✔
213
     * }];
2✔
214
     * session.call(methodsToCall,function(err,callResults) {
2✔
215
     *    if (!err) {
2✔
216
     *         const callResult = callResults[0];
2✔
217
     *         console.log(" statusCode = ",rep.statusCode);
2✔
218
     *         console.log(" inputArgumentResults[0] = ",callResult.inputArgumentResults[0].toString());
2✔
219
     *         console.log(" inputArgumentResults[1] = ",callResult.inputArgumentResults[1].toString());
2✔
220
     *         console.log(" outputArgument[0]       = ",callResult.outputArgument[0].toString()); // array of variant
2✔
221
     *    }
2✔
222
     * });
2✔
223
     * ```
2✔
224
     */
2✔
225

2✔
226
    call(methodToCall: CallMethodRequestLike): Promise<CallMethodResult>;
2✔
227
    call(methodsToCall: CallMethodRequestLike[]): Promise<CallMethodResult[]>;
2✔
228
    call(methodToCall: CallMethodRequestLike, callback: (err: Error | null, result?: CallMethodResult) => void): void;
2✔
229
    call(methodsToCall: CallMethodRequestLike[], callback: (err: Error | null, results?: CallMethodResult[]) => void): void;
2✔
230
}
2✔
231

2✔
232
// #endregion
2✔
233

2✔
234
// #region TranslateBrowsePath
2✔
235

2✔
236
export type BrowsePathLike = BrowsePathOptions;
2✔
237
export interface IBasicSessionTranslateBrowsePathAsyncSimple {
2✔
238
    translateBrowsePath(browsePath: BrowsePathLike): Promise<BrowsePathResult>;
2✔
239
}
2✔
240
export interface IBasicSessionTranslateBrowsePathAsyncMultiple {
2✔
241
    translateBrowsePath(browsePaths: BrowsePathLike[]): Promise<BrowsePathResult[]>;
2✔
242
}
2✔
243
export interface IBasicSessionTranslateBrowsePathAsync
2✔
244
    extends IBasicSessionTranslateBrowsePathAsyncSimple,
2✔
245
        IBasicSessionTranslateBrowsePathAsyncMultiple {
2✔
246
    translateBrowsePath(browsePath: BrowsePathLike): Promise<BrowsePathResult>;
2✔
247
    translateBrowsePath(browsePaths: BrowsePathLike[]): Promise<BrowsePathResult[]>;
2✔
248
}
2✔
249
export interface IBasicSessionTranslateBrowsePathCallback {
2✔
250
    translateBrowsePath(browsesPath: BrowsePathLike[], callback: ResponseCallback<BrowsePathResult[]>): void;
2✔
251
    translateBrowsePath(browsePath: BrowsePathLike, callback: ResponseCallback<BrowsePathResult>): void;
2✔
252
}
2✔
253
export interface IBasicSessionTranslateBrowsePath
2✔
254
    extends IBasicSessionTranslateBrowsePathCallback,
2✔
255
        IBasicSessionTranslateBrowsePathAsync {
2✔
256
    translateBrowsePath(browsePath: BrowsePathLike): Promise<BrowsePathResult>;
2✔
257
    translateBrowsePath(browsePaths: BrowsePathLike[]): Promise<BrowsePathResult[]>;
2✔
258
    translateBrowsePath(browsesPath: BrowsePathLike[], callback: ResponseCallback<BrowsePathResult[]>): void;
2✔
259
    translateBrowsePath(browsePath: BrowsePathLike, callback: ResponseCallback<BrowsePathResult>): void;
2✔
260
}
2✔
261

2✔
262
// #endregion
2✔
263

2✔
264
export interface IBasicSessionAsyncSimple extends 
2✔
265
        IBasicSessionBrowseAsyncSimple,
2✔
266
        IBasicSessionReadAsyncSimple,
2✔
267
        IBasicSessionWriteAsyncSimple,
2✔
268
        IBasicSessionCallAsyncSimple,
2✔
269
        IBasicSessionTranslateBrowsePathAsyncSimple {}
2✔
270

2✔
271

2✔
272
export interface IBasicSessionAsyncMultiple extends 
2✔
273
        IBasicSessionBrowseAsyncMultiple,
2✔
274
        IBasicSessionReadAsyncMultiple,
2✔
275
        IBasicSessionWriteAsyncMultiple,
2✔
276
        IBasicSessionCallAsyncMultiple,
2✔
277
        IBasicSessionTranslateBrowsePathAsyncMultiple {}
2✔
278

2✔
279
export interface IBasicSessionAsync extends  IBasicSessionBrowseAsync,
2✔
280
        IBasicSessionReadAsync,
2✔
281
        IBasicSessionWriteAsync,
2✔
282
        IBasicSessionCallAsync,
2✔
283
        IBasicSessionTranslateBrowsePathAsync {}
2✔
284
export type IVeryBasicSession = IBasicSessionAsync;
2✔
285

2✔
286
export interface IBasicSessionAsync2 extends IBasicSessionAsync, IBasicSessionBrowseNextAsync {}
2✔
287
export interface ITransportSettingProvider {
2✔
288
    getTransportSettings?: () => IBasicTransportSettings;
2✔
289
}
2✔
290

2✔
291
export interface IBasicSessionGetArgumentDefinitionCallback {
2✔
292
    getArgumentDefinition(methodId: MethodId, callback: (err: Error | null, args?: ArgumentDefinition) => void): void;
2✔
293
}
2✔
294
export interface IBasicSessionGetArgumentDefinitionAsync {
2✔
295
    getArgumentDefinition(methodId: MethodId): Promise<ArgumentDefinition>;
2✔
296
}
2✔
297
export interface IBasicSessionGetArgumentDefinition extends IBasicSessionGetArgumentDefinitionAsync, IBasicSessionGetArgumentDefinitionCallback {
2✔
298
    getArgumentDefinition(methodId: MethodId): Promise<ArgumentDefinition>;
2✔
299
    getArgumentDefinition(methodId: MethodId, callback: (err: Error | null, args?: ArgumentDefinition) => void): void;
2✔
300

2✔
301
}
2✔
302

2✔
303
export type IBasicSessionCallback = IBasicSessionReadCallback &
2✔
304
    IBasicSessionBrowseNextCallback &
2✔
305
    IBasicSessionBrowseCallback &
2✔
306
    IBasicSessionTranslateBrowsePathCallback &
2✔
307
    IBasicSessionGetArgumentDefinitionCallback &
2✔
308
    IBasicSessionWriteCallback;
2✔
309

2✔
310
export interface IBasicSession
2✔
311
    extends ITransportSettingProvider,
2✔
312
        IBasicSessionBrowse,
2✔
313
        IBasicSessionBrowseNext,
2✔
314
        IBasicSessionCall,
2✔
315
        IBasicSessionRead,
2✔
316
        IBasicSessionTranslateBrowsePath,
2✔
317
        IBasicSessionWrite,
2✔
318
        IBasicSessionGetArgumentDefinition {
2✔
319
}
2✔
320

2✔
321
export type PrivateKeyPEM = string;
2✔
322
export interface UserIdentityInfoUserName {
2✔
323
    type: UserTokenType.UserName;
2✔
324
    userName: string;
2✔
325
    password: string;
2✔
326
}
2✔
327

2✔
328
export interface UserIdentityInfoX509 extends X509IdentityTokenOptions {
2✔
329
    type: UserTokenType.Certificate;
2✔
330
    certificateData: ByteString;
2✔
331
    privateKey: PrivateKeyPEM;
2✔
332
}
2✔
333
export interface AnonymousIdentity {
2✔
334
    type: UserTokenType.Anonymous;
2✔
335
}
2✔
336

2✔
337
export type UserIdentityInfo = AnonymousIdentity | UserIdentityInfoX509 | UserIdentityInfoUserName;
2✔
338

2✔
339
export interface IBasicSessionChangeUser {
2✔
340
    changeUser(userIdentityInfo: UserIdentityInfo): Promise<StatusCode>;
2✔
341
    changeUser(userIdentityInfo: UserIdentityInfo, callback: CallbackT<StatusCode>): void;
2✔
342
}
2✔
343

2✔
344
function isValid(result: DataValue): boolean {
238✔
345
    assert(result.statusCode.isGood());
238✔
346
    if (result.value.dataType !== DataType.Null) {
238✔
347
        assert(result.value.dataType === DataType.ExtensionObject);
238✔
348
        assert(result.value.arrayType === VariantArrayType.Array);
238✔
349
    }
238✔
350
    return true;
238✔
351
}
238✔
352

2✔
353
export async function getArgumentDefinitionHelper(
2✔
354
    session: IBasicSessionBrowseAsyncSimple & IBasicSessionReadAsyncMultiple,
186✔
355
    methodId: MethodId
186✔
356
): Promise<ArgumentDefinition> {
186✔
357
    const browseDescription = new BrowseDescription({
186✔
358
        browseDirection: BrowseDirection.Forward,
186✔
359
        includeSubtypes: true,
186✔
360
        nodeClassMask: 0, // makeNodeClassMask("Variable"),
186✔
361
        nodeId: methodId,
186✔
362
        referenceTypeId: resolveNodeId("HasProperty"),
186✔
363
        resultMask: makeResultMask("BrowseName")
186✔
364
    });
186✔
365

186✔
366
    const browseResult = await session.browse(browseDescription);
186✔
367
    browseResult.references = browseResult.references || [];
186!
368

186✔
369
    const inputArgumentRefArray = browseResult.references.filter((r) => r.browseName.name === "InputArguments");
186✔
370

186✔
371
    // note : InputArguments property is optional thus may be missing
186✔
372
    const inputArgumentRef = inputArgumentRefArray.length === 1 ? inputArgumentRefArray[0] : null;
186✔
373

186✔
374
    const outputArgumentRefArray = browseResult.references.filter((r) => r.browseName.name === "OutputArguments");
186✔
375

186✔
376
    // note : OutputArguments property is optional thus may be missing
186✔
377
    const outputArgumentRef = outputArgumentRefArray.length === 1 ? outputArgumentRefArray[0] : null;
186✔
378

186✔
379
    let inputArguments: Argument[] = [];
186✔
380
    let outputArguments: Argument[] = [];
186✔
381

186✔
382
    const nodesToRead = [];
186✔
383
    const actions: any[] = [];
186✔
384

186✔
385
    if (inputArgumentRef) {
186✔
386
        nodesToRead.push({
150✔
387
            attributeId: AttributeIds.Value,
150✔
388
            nodeId: inputArgumentRef.nodeId
150✔
389
        });
150✔
390
        actions.push((result: DataValue) => {
150✔
391
            if (isValid(result)) {
150✔
392
                inputArguments = result.value.value as Argument[];
150✔
393
            }
150✔
394
        });
150✔
395
    }
150✔
396
    if (outputArgumentRef) {
186✔
397
        nodesToRead.push({
88✔
398
            attributeId: AttributeIds.Value,
88✔
399
            nodeId: outputArgumentRef.nodeId
88✔
400
        });
88✔
401
        actions.push((result: DataValue) => {
88✔
402
            assert(result.statusCode.isGood());
88✔
403
            if (isValid(result)) {
88✔
404
                outputArguments = result.value.value as Argument[];
88✔
405
            }
88✔
406
        });
88✔
407
    }
88✔
408

186✔
409
    if (nodesToRead.length === 0) {
186✔
410
        return { inputArguments, outputArguments };
32✔
411
    }
32✔
412
    // now read the variable
154✔
413
    const dataValues = await session.read(nodesToRead);
154✔
414

154✔
415
    dataValues.forEach((dataValue, index) => {
154✔
416
        actions[index].call(null, dataValue);
238✔
417
    });
154✔
418

154✔
419
    return { inputArguments, outputArguments };
154✔
420
}
154✔
421

2✔
422
interface SessionWithCache extends IBasicSessionAsync2 {
2✔
423
    $$namespaceArray?: string[] | null;
2✔
424
}
2✔
425

2✔
426

2✔
427
type ICascadingSession = { session?: IBasicSessionReadAsyncSimple }
2✔
428
function followSession(session: IBasicSessionReadAsyncSimple & ICascadingSession): SessionWithCache {
1,042✔
429
    if (session.session) {
1,042!
430
        return followSession(session.session);
×
UNCOV
431
    }
×
432
    return session as SessionWithCache;
1,042✔
433
}
1,042✔
434

2✔
435

2✔
436
export async function readNamespaceArray(session: IBasicSessionReadAsyncSimple): Promise<string[]> {
2✔
437

974✔
438
    const sessionHoldingCache = followSession(session) as SessionWithCache;
974✔
439
    if (sessionHoldingCache.$$namespaceArray)  {
974✔
440
        return sessionHoldingCache.$$namespaceArray!;
62✔
441
    }
62✔
442
    const nodeId = resolveNodeId(VariableIds.Server_NamespaceArray);
912✔
443

912✔
444
    const dataValue = await session.read({
912✔
445
        nodeId,
912✔
446
        attributeId: AttributeIds.Value
912✔
447
    });
912✔
448
    if (dataValue.statusCode.isNotGood()) {
974✔
449
        // errorLog("namespaceArray is not populated ! Your server must expose a list of namespaces in node ", nodeId.toString());
2✔
450
        return [];
2✔
451
    }
2✔
452
    sessionHoldingCache.$$namespaceArray = dataValue.value.value; // keep a cache
910✔
453
    return sessionHoldingCache.$$namespaceArray!;
910✔
454
}
910✔
455

2✔
456
export async function clearSessionCache(session: IBasicSessionAsync2) {
2✔
457
    const sessionHoldingCache = followSession(session) as SessionWithCache;
68✔
458
    sessionHoldingCache.$$namespaceArray = undefined;
68✔
459
}
68✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc