mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
6.2 KiB
163 lines
6.2 KiB
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.CoreFileSystemWritableFileStream = void 0;
|
|
const buffer_1 = require("@jsonjoy.com/fs-node-builtins/lib/internal/buffer");
|
|
const util_1 = require("./util");
|
|
const fs_node_utils_1 = require("@jsonjoy.com/fs-node-utils");
|
|
const WS = (typeof WritableStream === 'undefined' ? require('stream/web').WritableStream : WritableStream);
|
|
/**
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream
|
|
*/
|
|
class CoreFileSystemWritableFileStream extends WS {
|
|
constructor(core, path, keepExistingData = false, ctx) {
|
|
let fd;
|
|
super({
|
|
start: controller => {
|
|
if (ctx.locks.isLocked(path)) {
|
|
throw (0, util_1.newNoModificationAllowedError)();
|
|
}
|
|
ctx.locks.acquireLock(path);
|
|
const flags = keepExistingData ? fs_node_utils_1.FLAGS['r+'] : fs_node_utils_1.FLAGS.w;
|
|
try {
|
|
fd = core.open(path, flags, 438 /* MODE.FILE */);
|
|
}
|
|
catch (error) {
|
|
ctx.locks.releaseLock(path);
|
|
if (error && typeof error === 'object' && error.code === "EACCES" /* ERROR_CODE.EACCES */) {
|
|
throw (0, util_1.newNotAllowedError)();
|
|
}
|
|
throw error;
|
|
}
|
|
},
|
|
write: async (chunk) => {
|
|
await this._write(chunk);
|
|
},
|
|
close: async () => {
|
|
if (!this._closed && this._fd !== undefined) {
|
|
core.close(this._fd);
|
|
this._closed = true;
|
|
ctx.locks.releaseLock(path);
|
|
}
|
|
},
|
|
abort: async () => {
|
|
if (!this._closed && this._fd !== undefined) {
|
|
core.close(this._fd);
|
|
this._closed = true;
|
|
ctx.locks.releaseLock(path);
|
|
}
|
|
},
|
|
});
|
|
this._position = 0;
|
|
this._closed = false;
|
|
this._core = core;
|
|
this._path = path;
|
|
this._fd = fd;
|
|
this._ctx = ctx;
|
|
}
|
|
/**
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream/seek
|
|
*/
|
|
async seek(position) {
|
|
if (this._closed) {
|
|
throw new DOMException('The stream is closed.', 'InvalidStateError');
|
|
}
|
|
this._position = position;
|
|
}
|
|
/**
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream/truncate
|
|
*/
|
|
async truncate(size) {
|
|
if (this._closed) {
|
|
throw new DOMException('The stream is closed.', 'InvalidStateError');
|
|
}
|
|
try {
|
|
const link = this._core.getResolvedLinkOrThrow(this._path);
|
|
const node = link.getNode();
|
|
node.truncate(size);
|
|
}
|
|
catch (error) {
|
|
if (error && typeof error === 'object' && error.code === "EACCES" /* ERROR_CODE.EACCES */) {
|
|
throw (0, util_1.newNotAllowedError)();
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
async write(chunkOrParams) {
|
|
await this._write(chunkOrParams);
|
|
}
|
|
async _write(chunkOrParams) {
|
|
if (this._closed) {
|
|
throw new DOMException('The stream is closed.', 'InvalidStateError');
|
|
}
|
|
if (this._fd === undefined) {
|
|
throw new DOMException('The stream is not ready.', 'InvalidStateError');
|
|
}
|
|
try {
|
|
if (this._isParams(chunkOrParams)) {
|
|
const params = chunkOrParams;
|
|
switch (params.type) {
|
|
case 'write': {
|
|
if (params.data !== undefined) {
|
|
const buffer = this._dataToBuffer(params.data);
|
|
const position = params.position !== undefined ? params.position : this._position;
|
|
const written = this._core.write(this._fd, buffer, 0, buffer.length, position);
|
|
if (params.position === undefined) {
|
|
this._position += written;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 'seek': {
|
|
if (params.position !== undefined) {
|
|
this._position = params.position;
|
|
}
|
|
break;
|
|
}
|
|
case 'truncate': {
|
|
if (params.size !== undefined) {
|
|
await this.truncate(params.size);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// Direct data write
|
|
const buffer = this._dataToBuffer(chunkOrParams);
|
|
const written = this._core.write(this._fd, buffer, 0, buffer.length, this._position);
|
|
this._position += written;
|
|
}
|
|
}
|
|
catch (error) {
|
|
if (error && typeof error === 'object' && error.code === "EACCES" /* ERROR_CODE.EACCES */) {
|
|
throw (0, util_1.newNotAllowedError)();
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
_isParams(chunk) {
|
|
return !!(chunk && typeof chunk === 'object' && 'type' in chunk);
|
|
}
|
|
_dataToBuffer(data) {
|
|
if (typeof data === 'string') {
|
|
return buffer_1.Buffer.from(data, 'utf8');
|
|
}
|
|
if (data instanceof buffer_1.Buffer) {
|
|
return data;
|
|
}
|
|
if (data instanceof ArrayBuffer) {
|
|
return buffer_1.Buffer.from(data);
|
|
}
|
|
if (ArrayBuffer.isView(data)) {
|
|
return buffer_1.Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
}
|
|
if (data instanceof Blob) {
|
|
// For Blob, we would need to read it asynchronously
|
|
// This is a simplified implementation
|
|
throw new Error('Blob data type not fully supported in this implementation');
|
|
}
|
|
throw new Error('Unsupported data type');
|
|
}
|
|
}
|
|
exports.CoreFileSystemWritableFileStream = CoreFileSystemWritableFileStream;
|
|
//# sourceMappingURL=CoreFileSystemWritableFileStream.js.map
|