node-opcua-file-transfer 2.178.0 → 2.180.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/dist/client/client_file.d.ts +4 -4
- package/dist/client/client_file.js +30 -27
- package/dist/client/client_file.js.map +1 -1
- package/dist/client/read_file.d.ts +1 -1
- package/dist/client/read_file.js +1 -1
- package/dist/client/read_file.js.map +1 -1
- package/dist/client/read_max_byte_string_length.d.ts +1 -1
- package/dist/client/read_max_byte_string_length.js.map +1 -1
- package/dist/client/write_file.d.ts +1 -1
- package/dist/client/write_file.js +4 -3
- package/dist/client/write_file.js.map +1 -1
- package/dist/common/abstract_fs.d.ts +1 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/open_mode.js +7 -0
- package/dist/open_mode.js.map +1 -1
- package/dist/server/file_type_helpers.d.ts +3 -3
- package/dist/server/file_type_helpers.js +36 -34
- package/dist/server/file_type_helpers.js.map +1 -1
- package/package.json +24 -24
- package/source/client/client_file.ts +38 -35
- package/source/client/read_file.ts +2 -4
- package/source/client/read_max_byte_string_length.ts +2 -5
- package/source/client/write_file.ts +5 -6
- package/source/common/abstract_fs.ts +2 -4
- package/source/index.ts +1 -1
- package/source/open_mode.ts +9 -2
- package/source/server/file_type_helpers.ts +37 -44
|
@@ -2,30 +2,21 @@
|
|
|
2
2
|
* @module node-opcua-file-transfer
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
import { assert } from "node-opcua-assert";
|
|
5
|
+
import fsOrig from "node:fs";
|
|
6
|
+
import { promisify, types } from "node:util";
|
|
7
|
+
import type { IAddressSpace, ISessionContext, UAFile, UAFile_Base, UAMethod, UAObjectType } from "node-opcua-address-space";
|
|
9
8
|
import { getContextMaxMessageSize } from "node-opcua-address-space-base";
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
ISessionContext,
|
|
13
|
-
UAFile,
|
|
14
|
-
UAFile_Base,
|
|
15
|
-
UAMethod,
|
|
16
|
-
UAObjectType
|
|
17
|
-
} from "node-opcua-address-space";
|
|
18
|
-
import { Byte, Int32, UInt32, UInt64 } from "node-opcua-basic-types";
|
|
9
|
+
import { assert } from "node-opcua-assert";
|
|
10
|
+
import type { Byte, Int32, UInt32, UInt64 } from "node-opcua-basic-types";
|
|
19
11
|
import { BinaryStream } from "node-opcua-binary-stream";
|
|
12
|
+
import { DataValue } from "node-opcua-data-value";
|
|
20
13
|
import { checkDebugFlag, make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
|
|
21
|
-
import { NodeId, NodeIdLike, sameNodeId } from "node-opcua-nodeid";
|
|
22
|
-
import { CallMethodResultOptions } from "node-opcua-service-call";
|
|
14
|
+
import { NodeId, type NodeIdLike, sameNodeId } from "node-opcua-nodeid";
|
|
15
|
+
import type { CallMethodResultOptions } from "node-opcua-service-call";
|
|
23
16
|
import { StatusCodes } from "node-opcua-status-code";
|
|
24
17
|
import { DataType, Variant, VariantArrayType } from "node-opcua-variant";
|
|
25
|
-
import {
|
|
26
|
-
|
|
18
|
+
import type { AbstractFs } from "../common/abstract_fs";
|
|
27
19
|
import { OpenFileMode, OpenFileModeMask } from "../open_mode";
|
|
28
|
-
import { AbstractFs } from "../common/abstract_fs";
|
|
29
20
|
|
|
30
21
|
const debugLog = make_debugLog("FileType");
|
|
31
22
|
const errorLog = make_errorLog("FileType");
|
|
@@ -63,7 +54,7 @@ export interface FileOptions {
|
|
|
63
54
|
refreshFileContentFunc?: () => Promise<void>;
|
|
64
55
|
}
|
|
65
56
|
|
|
66
|
-
export interface UAFileType extends UAObjectType, UAFile_Base {
|
|
57
|
+
export interface UAFileType extends UAObjectType, UAFile_Base {}
|
|
67
58
|
/**
|
|
68
59
|
*
|
|
69
60
|
*/
|
|
@@ -88,7 +79,7 @@ export class FileTypeData {
|
|
|
88
79
|
this.refreshFileContentFunc = options.refreshFileContentFunc;
|
|
89
80
|
|
|
90
81
|
this.filename = options.filename;
|
|
91
|
-
this.maxSize = options.maxSize
|
|
82
|
+
this.maxSize = options.maxSize ?? 0;
|
|
92
83
|
this.mimeType = options.mimeType || "";
|
|
93
84
|
this.maxChunkSizeBytes = options.maxChunkSize || FileTypeData.maxChunkSize;
|
|
94
85
|
|
|
@@ -102,30 +93,30 @@ export class FileTypeData {
|
|
|
102
93
|
);
|
|
103
94
|
file.openCount.minimumSamplingInterval = 0; // changes immediately
|
|
104
95
|
|
|
105
|
-
const readFileSize =
|
|
96
|
+
const readFileSize = (): { size: number; timestamp: Date } => {
|
|
106
97
|
const stat = (this._fs as AbstractFs).statSync(this.filename);
|
|
107
98
|
|
|
108
99
|
const size = stat.size;
|
|
109
100
|
const timestamp = stat.mtime;
|
|
110
101
|
return { size, timestamp };
|
|
111
|
-
}
|
|
102
|
+
};
|
|
112
103
|
|
|
113
104
|
const data = this;
|
|
114
105
|
file.size.bindVariable(
|
|
115
106
|
{
|
|
116
|
-
timestamped_get():
|
|
107
|
+
timestamped_get(): DataValue {
|
|
117
108
|
try {
|
|
118
109
|
const { size, timestamp } = readFileSize();
|
|
119
110
|
data.fileSize = size;
|
|
120
111
|
return new DataValue({
|
|
121
112
|
sourceTimestamp: timestamp,
|
|
122
|
-
serverTimestamp:
|
|
113
|
+
serverTimestamp: new Date(),
|
|
123
114
|
value: new Variant({ dataType: DataType.UInt64, value: data._fileSize }),
|
|
124
115
|
statusCode: StatusCodes.Good
|
|
125
116
|
});
|
|
126
|
-
} catch (
|
|
117
|
+
} catch (_err) {
|
|
127
118
|
return new DataValue({
|
|
128
|
-
serverTimestamp:
|
|
119
|
+
serverTimestamp: new Date(),
|
|
129
120
|
statusCode: StatusCodes.BadDataUnavailable
|
|
130
121
|
});
|
|
131
122
|
}
|
|
@@ -175,7 +166,8 @@ export class FileTypeData {
|
|
|
175
166
|
}
|
|
176
167
|
const stat = await promisify(abstractFs.stat)(self.filename);
|
|
177
168
|
self._fileSize = stat.size;
|
|
178
|
-
|
|
169
|
+
// c8 ignore next
|
|
170
|
+
doDebug && debugLog("original file size ", self.filename, " size = ", self._fileSize);
|
|
179
171
|
} catch (err) {
|
|
180
172
|
self._fileSize = 0;
|
|
181
173
|
if (types.isNativeError(err)) {
|
|
@@ -249,8 +241,8 @@ interface FileTypeM {
|
|
|
249
241
|
$$files: { [key: number]: FileAccessData };
|
|
250
242
|
}
|
|
251
243
|
|
|
252
|
-
interface AddressSpacePriv extends IAddressSpace, FileTypeM {
|
|
253
|
-
function _prepare(addressSpace: IAddressSpace
|
|
244
|
+
interface AddressSpacePriv extends IAddressSpace, FileTypeM {}
|
|
245
|
+
function _prepare(addressSpace: IAddressSpace): FileTypeM {
|
|
254
246
|
const _context = addressSpace as AddressSpacePriv;
|
|
255
247
|
_context.$$currentFileHandle = _context.$$currentFileHandle ? _context.$$currentFileHandle : 41;
|
|
256
248
|
_context.$$files = _context.$$files || {};
|
|
@@ -260,11 +252,11 @@ function _getSessionId(context: ISessionContext) {
|
|
|
260
252
|
if (!context.session) {
|
|
261
253
|
return new NodeId();
|
|
262
254
|
}
|
|
263
|
-
assert(context.session
|
|
255
|
+
assert(context.session?.getSessionId);
|
|
264
256
|
return context.session?.getSessionId() || new NodeId();
|
|
265
257
|
}
|
|
266
258
|
function _addFile(addressSpace: IAddressSpace, context: ISessionContext, openMode: OpenFileMode): UInt32 {
|
|
267
|
-
const _context = _prepare(addressSpace
|
|
259
|
+
const _context = _prepare(addressSpace);
|
|
268
260
|
_context.$$currentFileHandle++;
|
|
269
261
|
const fileHandle: number = _context.$$currentFileHandle;
|
|
270
262
|
const sessionId = _getSessionId(context);
|
|
@@ -282,7 +274,7 @@ function _addFile(addressSpace: IAddressSpace, context: ISessionContext, openMod
|
|
|
282
274
|
}
|
|
283
275
|
|
|
284
276
|
function _getFileInfo(addressSpace: IAddressSpace, context: ISessionContext, fileHandle: UInt32): FileAccessData | null {
|
|
285
|
-
const _context = _prepare(addressSpace
|
|
277
|
+
const _context = _prepare(addressSpace);
|
|
286
278
|
const _fileInfo = _context.$$files[fileHandle];
|
|
287
279
|
const sessionId = _getSessionId(context);
|
|
288
280
|
|
|
@@ -293,8 +285,8 @@ function _getFileInfo(addressSpace: IAddressSpace, context: ISessionContext, fil
|
|
|
293
285
|
return _fileInfo;
|
|
294
286
|
}
|
|
295
287
|
|
|
296
|
-
function _close(addressSpace: IAddressSpace,
|
|
297
|
-
const _context = _prepare(addressSpace
|
|
288
|
+
function _close(addressSpace: IAddressSpace, fileData: FileAccessData) {
|
|
289
|
+
const _context = _prepare(addressSpace);
|
|
298
290
|
delete _context.$$files[fileData.handle];
|
|
299
291
|
}
|
|
300
292
|
|
|
@@ -373,7 +365,7 @@ async function _openFile(this: UAMethod, inputArguments: Variant[], context: ISe
|
|
|
373
365
|
|
|
374
366
|
const flags = toNodeJSMode(mode);
|
|
375
367
|
if (flags === "?") {
|
|
376
|
-
errorLog(
|
|
368
|
+
errorLog(`Invalid mode ${OpenFileMode[mode]} (${mode})`);
|
|
377
369
|
return { statusCode: StatusCodes.BadInvalidArgument };
|
|
378
370
|
}
|
|
379
371
|
|
|
@@ -412,7 +404,6 @@ async function _openFile(this: UAMethod, inputArguments: Variant[], context: ISe
|
|
|
412
404
|
const fileLength = (await promisify(abstractFs.stat)(filename)).size;
|
|
413
405
|
_fileInfo.size = fileLength;
|
|
414
406
|
|
|
415
|
-
// tslint:disable-next-line:no-bitwise
|
|
416
407
|
if ((mode & OpenFileModeMask.AppendBit) === OpenFileModeMask.AppendBit) {
|
|
417
408
|
_fileInfo.position[1] = fileLength;
|
|
418
409
|
}
|
|
@@ -429,7 +420,8 @@ async function _openFile(this: UAMethod, inputArguments: Variant[], context: ISe
|
|
|
429
420
|
return { statusCode: StatusCodes.BadUnexpectedError };
|
|
430
421
|
}
|
|
431
422
|
|
|
432
|
-
|
|
423
|
+
// c8 ignore next
|
|
424
|
+
doDebug && debugLog("Opening file handle ", fileHandle, "filename: ", fileData.filename, "openCount: ", fileData.openCount);
|
|
433
425
|
|
|
434
426
|
const callMethodResult = {
|
|
435
427
|
outputArguments: [
|
|
@@ -470,10 +462,11 @@ async function _closeFile(this: UAMethod, inputArguments: Variant[], context: IS
|
|
|
470
462
|
|
|
471
463
|
const fileData = getFileDataFromContext(context);
|
|
472
464
|
|
|
473
|
-
|
|
465
|
+
// c8 ignore next
|
|
466
|
+
doDebug && debugLog("Closing file handle ", fileHandle, "filename: ", fileData.filename, "openCount: ", fileData.openCount);
|
|
474
467
|
|
|
475
468
|
await promisify(abstractFs.close)(_fileInfo.fd);
|
|
476
|
-
_close(addressSpace,
|
|
469
|
+
_close(addressSpace, _fileInfo);
|
|
477
470
|
fileData.openCount -= 1;
|
|
478
471
|
|
|
479
472
|
return {
|
|
@@ -513,7 +506,6 @@ async function _readFile(this: UAMethod, inputArguments: Variant[], context: ISe
|
|
|
513
506
|
if (!_fileInfo) {
|
|
514
507
|
return { statusCode: StatusCodes.BadInvalidState };
|
|
515
508
|
}
|
|
516
|
-
// tslint:disable-next-line:no-bitwise
|
|
517
509
|
if ((_fileInfo.openMode & OpenFileModeMask.ReadBit) === 0x0) {
|
|
518
510
|
// open mode did not specify Read Flag
|
|
519
511
|
return { statusCode: StatusCodes.BadInvalidState };
|
|
@@ -550,7 +542,7 @@ async function _readFile(this: UAMethod, inputArguments: Variant[], context: ISe
|
|
|
550
542
|
try {
|
|
551
543
|
// note: we do not util.promise here as it has a wierd behavior...
|
|
552
544
|
ret = await new Promise((resolve, reject) =>
|
|
553
|
-
abstractFs.read(_fileInfo.fd, data, 0, length, _fileInfo.position[1], (err, bytesRead,
|
|
545
|
+
abstractFs.read(_fileInfo.fd, data, 0, length, _fileInfo.position[1], (err, bytesRead, _buff) => {
|
|
554
546
|
if (err) {
|
|
555
547
|
return reject(err);
|
|
556
548
|
}
|
|
@@ -585,7 +577,6 @@ async function _writeFile(this: UAMethod, inputArguments: Variant[], context: IS
|
|
|
585
577
|
return { statusCode: StatusCodes.BadInvalidArgument };
|
|
586
578
|
}
|
|
587
579
|
|
|
588
|
-
// tslint:disable-next-line:no-bitwise
|
|
589
580
|
if ((_fileInfo.openMode & OpenFileModeMask.WriteBit) === 0x00) {
|
|
590
581
|
// File has not been open with write mode
|
|
591
582
|
return { statusCode: StatusCodes.BadInvalidState };
|
|
@@ -610,9 +601,11 @@ async function _writeFile(this: UAMethod, inputArguments: Variant[], context: IS
|
|
|
610
601
|
_fileInfo.size = Math.max(_fileInfo.size, _fileInfo.position[1]);
|
|
611
602
|
|
|
612
603
|
const fileData = getFileDataFromContext(context);
|
|
613
|
-
|
|
604
|
+
// c8 ignore next
|
|
605
|
+
doDebug && debugLog(fileData.fileSize);
|
|
614
606
|
fileData.fileSize = Math.max(fileData.fileSize, _fileInfo.position[1]);
|
|
615
|
-
|
|
607
|
+
// c8 ignore next
|
|
608
|
+
doDebug && debugLog(fileData.fileSize);
|
|
616
609
|
} catch (err) {
|
|
617
610
|
if (types.isNativeError(err)) {
|
|
618
611
|
errorLog("Write error : ", err.message);
|