New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@zenfs/core

Package Overview
Dependencies
Maintainers
1
Versions
165
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@zenfs/core - npm Package Compare versions

Comparing version 0.8.1 to 0.9.0

dist/backends/FileIndex.d.ts

10

dist/backends/AsyncStore.d.ts

@@ -86,10 +86,4 @@ import type { Cred } from '../cred.js';

openFile(path: string, flag: string, cred: Cred): Promise<import("../file.js").File>;
createFile(path: string, flag: string, mode: number, cred: Cred): Promise<import("../file.js").File>; /**
* Promise that resolves to the store
*/
unlink(path: string, cred: Cred): Promise<void>; /**
* An asynchronous file system which uses an async store to store its data.
* @see AsyncStore
* @internal
*/
createFile(path: string, flag: string, mode: number, cred: Cred): Promise<import("../file.js").File>;
unlink(path: string, cred: Cred): Promise<void>;
rmdir(path: string, cred: Cred): Promise<void>;

@@ -96,0 +90,0 @@ mkdir(path: string, mode: number, cred: Cred): Promise<void>;

16

dist/backends/Overlay.js

@@ -120,3 +120,3 @@ import { FileSystem } from '../filesystem.js';

if (this._deletedFiles.has(oldPath)) {
throw ApiError.With('ENOENT', oldPath, 'renameSync');
throw ApiError.With('ENOENT', oldPath, 'rename');
}

@@ -147,3 +147,3 @@ }

if (this._deletedFiles.has(p)) {
throw ApiError.With('ENOENT', p, 'statSync');
throw ApiError.With('ENOENT', p, 'stat');
}

@@ -213,3 +213,3 @@ const oldStat = new Stats(this._readable.statSync(p, cred));

if (!this.existsSync(p, cred)) {
throw ApiError.With('ENOENT', p, 'unlinkSync');
throw ApiError.With('ENOENT', p, 'unlink');
}

@@ -245,3 +245,3 @@ if (this._writable.existsSync(p, cred)) {

if (!this.existsSync(p, cred)) {
throw ApiError.With('ENOENT', p, 'rmdirSync');
throw ApiError.With('ENOENT', p, 'rmdir');
}

@@ -254,3 +254,3 @@ if (this._writable.existsSync(p, cred)) {

if (this.readdirSync(p, cred).length > 0) {
throw ApiError.With('ENOTEMPTY', p, 'rmdirSync');
throw ApiError.With('ENOTEMPTY', p, 'rmdir');
}

@@ -274,3 +274,3 @@ else {

if (this.existsSync(p, cred)) {
throw ApiError.With('EEXIST', p, 'mkdirSync');
throw ApiError.With('EEXIST', p, 'mkdir');
}

@@ -312,3 +312,3 @@ // The below will throw should any of the parent directories fail to exist on _writable.

if (!dirStats.isDirectory()) {
throw ApiError.With('ENOTDIR', p, 'readdirSync');
throw ApiError.With('ENOTDIR', p, 'readdir');
}

@@ -432,3 +432,3 @@ // Readdir in both, check delete log on RO file system's listing, merge, return.

if (!(await this.exists(p, cred))) {
throw ApiError.With('ENOENT', p, 'operateOnWritableAsync');
throw ApiError.With('ENOENT', p, 'operateOnWritable');
}

@@ -435,0 +435,0 @@ if (!(await this._writable.exists(p, cred))) {

@@ -113,6 +113,6 @@ import { dirname, basename, join, resolve, sep } from '../emulation/path.js';

if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {
throw ApiError.With('EACCES', oldPath, 'renameSync');
throw ApiError.With('EACCES', oldPath, 'rename');
}
if (!oldDirList[oldName]) {
throw ApiError.With('ENOENT', oldPath, 'renameSync');
throw ApiError.With('ENOENT', oldPath, 'rename');
}

@@ -155,3 +155,3 @@ const ino = oldDirList[oldName];

// If it's a directory, throw a permissions error.
throw ApiError.With('EPERM', newPath, 'renameSync');
throw ApiError.With('EPERM', newPath, 'rename');
}

@@ -175,3 +175,3 @@ }

if (!stats.hasAccess(R_OK, cred)) {
throw ApiError.With('EACCES', p, 'statSync');
throw ApiError.With('EACCES', p, 'stat');
}

@@ -187,6 +187,6 @@ return stats;

if (!node.toStats().hasAccess(flagToMode(flag), cred)) {
throw ApiError.With('EACCES', p, 'openFileSync');
throw ApiError.With('EACCES', p, 'openFile');
}
if (data === null) {
throw ApiError.With('ENOENT', p, 'openFileSync');
throw ApiError.With('ENOENT', p, 'openFile');
}

@@ -201,3 +201,3 @@ return new PreloadFile(this, p, flag, node.toStats(), data);

if (this.readdirSync(p, cred).length > 0) {
throw ApiError.With('ENOTEMPTY', p, 'rmdirSync');
throw ApiError.With('ENOTEMPTY', p, 'rmdir');
}

@@ -215,3 +215,3 @@ else {

if (!node.toStats().hasAccess(R_OK, cred)) {
throw ApiError.With('EACCES', p, 'readdirSync');
throw ApiError.With('EACCES', p, 'readdir');
}

@@ -243,7 +243,7 @@ return Object.keys(this.getDirListing(tx, node, p));

if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {
throw ApiError.With('EACCES', existingDir, 'linkSync');
throw ApiError.With('EACCES', existingDir, 'link');
}
const newDir = dirname(newpath), newDirNode = this.findINode(tx, newDir), newListing = this.getDirListing(tx, newDirNode, newDir);
if (!newDirNode.toStats().hasAccess(W_OK, cred)) {
throw ApiError.With('EACCES', newDir, 'linkSync');
throw ApiError.With('EACCES', newDir, 'link');
}

@@ -253,3 +253,3 @@ const ino = this._findINode(tx, existingDir, basename(existing));

if (!node.toStats().hasAccess(W_OK, cred)) {
throw ApiError.With('EACCES', newpath, 'linkSync');
throw ApiError.With('EACCES', newpath, 'link');
}

@@ -256,0 +256,0 @@ node.nlink++;

@@ -7,4 +7,5 @@ /// <reference types="node" resolution-mode="require"/>

import { BigIntStats, type BigIntStatsFs, type Stats, type StatsFs } from '../stats.js';
import type { Callback } from '../utils.js';
import { type Callback } from '../utils.js';
import { Dirent, type Dir } from './dir.js';
import * as promises from './promises.js';
import { PathLike } from './shared.js';

@@ -379,21 +380,46 @@ import { ReadStream, WriteStream } from './streams.js';

}, listener?: (event: string, filename: string) => any): Node.FSWatcher;
/**
* @todo Implement
*/
export declare function createReadStream(path: PathLike, options?: {
interface StreamOptions {
flags?: string;
encoding?: string;
fd?: number;
encoding?: BufferEncoding;
fd?: number | promises.FileHandle;
mode?: number;
autoClose?: boolean;
}): ReadStream;
emitClose?: boolean;
start?: number;
signal?: AbortSignal;
highWaterMark?: number;
}
interface FSImplementation {
open?: (...args: any[]) => unknown;
close?: (...args: any[]) => unknown;
}
interface ReadStreamOptions extends StreamOptions {
fs?: FSImplementation & {
read: (...args: any[]) => unknown;
};
end?: number;
}
interface WriteStreamOptions extends StreamOptions {
fs?: FSImplementation & {
write: (...args: any[]) => unknown;
writev?: (...args: any[]) => unknown;
};
flush?: boolean;
}
/**
* @todo Implement
* Opens a file in read mode and creates a Node.js-like ReadStream.
*
* @param path The path to the file to be opened.
* @param options Options for the ReadStream and file opening (e.g., `encoding`, `highWaterMark`, `mode`).
* @returns A ReadStream object for interacting with the file's contents.
*/
export declare function createWriteStream(path: PathLike, options?: {
flags?: string;
encoding?: string;
fd?: number;
mode?: number;
}): WriteStream;
export declare function createReadStream(path: PathLike, _options?: BufferEncoding | ReadStreamOptions): ReadStream;
/**
* Opens a file in write mode and creates a Node.js-like WriteStream.
*
* @param path The path to the file to be opened.
* @param options Options for the WriteStream and file opening (e.g., `encoding`, `highWaterMark`, `mode`).
* @returns A WriteStream object for writing to the file.
*/
export declare function createWriteStream(path: PathLike, _options?: BufferEncoding | WriteStreamOptions): WriteStream;
export declare function rm(path: PathLike, callback: Callback): void;

@@ -411,7 +437,7 @@ export declare function rm(path: PathLike, options: Node.RmOptions, callback: Callback): void;

type readvCb = Callback<[number, NodeJS.ArrayBufferView[]]>;
export declare function readv(fd: number, buffers: readonly NodeJS.ArrayBufferView[], cb: readvCb): void;
export declare function readv(fd: number, buffers: readonly NodeJS.ArrayBufferView[], position: number, cb: readvCb): void;
export declare function readv(fd: number, buffers: NodeJS.ArrayBufferView[], cb: readvCb): void;
export declare function readv(fd: number, buffers: NodeJS.ArrayBufferView[], position: number, cb: readvCb): void;
type writevCb = Callback<[number, NodeJS.ArrayBufferView[]]>;
export declare function writev(fd: number, buffers: NodeJS.ArrayBufferView[], cb: writevCb): void;
export declare function writev(fd: number, buffers: NodeJS.ArrayBufferView[], position: number, cb: writevCb): void;
export declare function writev(fd: number, buffers: Uint8Array[], cb: writevCb): void;
export declare function writev(fd: number, buffers: Uint8Array[], position: number, cb: writevCb): void;
export declare function opendir(path: PathLike, cb: Callback<[Dir]>): void;

@@ -428,3 +454,2 @@ export declare function opendir(path: PathLike, options: Node.OpenDirOptions, cb: Callback<[Dir]>): void;

}, callback: Callback<[BigIntStatsFs]>): void;
export declare function openAsBlob(path: PathLike, options?: Node.OpenAsBlobOptions): Promise<Blob>;
export {};
import { ApiError, ErrorCode } from '../ApiError.js';
import { BigIntStats } from '../stats.js';
import { nop, normalizeMode } from '../utils.js';
import { R_OK } from './constants.js';
import * as promises from './promises.js';
import { fd2file, nop, normalizeMode } from './shared.js';
import { fd2file } from './shared.js';
import { ReadStream, WriteStream } from './streams.js';
/**

@@ -432,3 +434,3 @@ * Asynchronous rename. No arguments other than a possible exception are given

export function watchFile(filename, optsListener, listener = nop) {
throw ApiError.With('ENOTSUP', filename, 'watchFile');
throw ApiError.With('ENOSYS', filename, 'watchFile');
}

@@ -440,21 +442,87 @@ watchFile;

export function unwatchFile(filename, listener = nop) {
throw ApiError.With('ENOTSUP', filename, 'unwatchFile');
throw ApiError.With('ENOSYS', filename, 'unwatchFile');
}
unwatchFile;
export function watch(filename, options, listener = nop) {
throw ApiError.With('ENOTSUP', filename, 'watch');
throw ApiError.With('ENOSYS', filename, 'watch');
}
watch;
/**
* @todo Implement
* Opens a file in read mode and creates a Node.js-like ReadStream.
*
* @param path The path to the file to be opened.
* @param options Options for the ReadStream and file opening (e.g., `encoding`, `highWaterMark`, `mode`).
* @returns A ReadStream object for interacting with the file's contents.
*/
export function createReadStream(path, options) {
throw ApiError.With('ENOTSUP', path, 'createReadStream');
export function createReadStream(path, _options) {
const options = typeof _options == 'object' ? _options : { encoding: _options };
let handle;
const stream = new ReadStream({
highWaterMark: options.highWaterMark || 64 * 1024,
encoding: options.encoding || 'utf8',
async read(size) {
try {
handle || (handle = await promises.open(path, 'r', options?.mode));
const result = await handle.read(new Uint8Array(size), 0, size, handle.file.position);
stream.push(!result.bytesRead ? null : result.buffer.slice(0, result.bytesRead));
handle.file.position += result.bytesRead;
if (!result.bytesRead) {
await handle.close();
}
}
catch (error) {
await handle?.close();
stream.destroy(error);
}
},
destroy(error, callback) {
handle
?.close()
.then(() => callback(error))
.catch(callback);
},
});
stream.path = path;
return stream;
}
createReadStream;
/**
* @todo Implement
* Opens a file in write mode and creates a Node.js-like WriteStream.
*
* @param path The path to the file to be opened.
* @param options Options for the WriteStream and file opening (e.g., `encoding`, `highWaterMark`, `mode`).
* @returns A WriteStream object for writing to the file.
*/
export function createWriteStream(path, options) {
throw ApiError.With('ENOTSUP', path, 'createWriteStream');
export function createWriteStream(path, _options) {
const options = typeof _options == 'object' ? _options : { encoding: _options };
let handle;
const stream = new WriteStream({
highWaterMark: options?.highWaterMark,
async write(chunk, encoding, callback) {
try {
handle || (handle = await promises.open(path, 'w', options?.mode || 0o666));
await handle.write(chunk, null, encoding);
callback(null);
}
catch (error) {
await handle?.close();
callback(error);
}
},
destroy(error, callback) {
callback(error);
handle
?.close()
.then(() => callback(error))
.catch(callback);
},
final(callback) {
handle
?.close()
.then(() => callback())
.catch(callback);
},
});
stream.path = path;
return stream;
}

@@ -526,7 +594,1 @@ createWriteStream;

statfs;
/* eslint-disable @typescript-eslint/no-unused-vars */
export function openAsBlob(path, options) {
throw ApiError.With('ENOTSUP', path, 'openAsBlob');
}
openAsBlob;
/* eslint-enable @typescript-eslint/no-unused-vars */

@@ -7,3 +7,3 @@ export * from './async.js';

export * from './dir.js';
export { mountMapping, mounts, mount, umount, _toUnixTimestamp } from './shared.js';
export { mountMapping, mounts, mount, umount } from './shared.js';
export { Stats, BigIntStats, StatsFs } from '../stats.js';

@@ -7,3 +7,3 @@ export * from './async.js';

export * from './dir.js';
export { mountMapping, mounts, mount, umount, _toUnixTimestamp } from './shared.js';
export { mountMapping, mounts, mount, umount } from './shared.js';
export { Stats, BigIntStats, StatsFs } from '../stats.js';

@@ -11,10 +11,14 @@ /// <reference types="node" resolution-mode="require"/>

import type { CreateReadStreamOptions, CreateWriteStreamOptions, FileChangeInfo, FileReadResult, FlagAndOpenMode } from 'node:fs/promises';
import type { ReadableStream } from 'node:stream/web';
import type { ReadableStream as TReadableStream } from 'node:stream/web';
import type { Interface as ReadlineInterface } from 'readline';
import { File } from '../file.js';
import { FileContents } from '../filesystem.js';
import { BigIntStats, type BigIntStatsFs, type Stats, type StatsFs } from '../stats.js';
import { Dirent, type Dir } from './dir.js';
import { Dir, Dirent } from './dir.js';
import type { PathLike } from './shared.js';
import { ReadStream, WriteStream } from './streams.js';
export * as constants from './constants.js';
declare global {
const ReadableStream: typeof TReadableStream;
}
export declare class FileHandle implements promises.FileHandle {

@@ -30,5 +34,7 @@ /**

fd: number);
private get file();
private get path();
/**
* @internal
*/
get file(): File;
/**
* Asynchronous fchown(2) - Change ownership of a file.

@@ -102,3 +108,3 @@ */

*/
readableWebStream(options?: promises.ReadableWebStreamOptions): ReadableStream;
readableWebStream(options?: promises.ReadableWebStreamOptions): TReadableStream<Uint8Array>;
readLines(options?: promises.CreateReadStreamOptions): ReadlineInterface;

@@ -159,12 +165,28 @@ [Symbol.asyncDispose](): Promise<void>;

/**
* See `fs.writev` promisified version.
* @todo Implement
* Asynchronous `writev`. Writes from multiple buffers.
* @param buffers An array of Uint8Array buffers.
* @param position The position in the file where to begin writing.
* @returns The number of bytes written.
*/
writev(buffers: NodeJS.ArrayBufferView[], position?: number): Promise<Node.WriteVResult>;
writev(buffers: Uint8Array[], position?: number): Promise<Node.WriteVResult>;
/**
* See `fs.readv` promisified version.
* @todo Implement
* Asynchronous `readv`. Reads into multiple buffers.
* @param buffers An array of Uint8Array buffers.
* @param position The position in the file where to begin reading.
* @returns The number of bytes read.
*/
readv(buffers: readonly NodeJS.ArrayBufferView[], position?: number): Promise<Node.ReadVResult>;
readv(buffers: NodeJS.ArrayBufferView[], position?: number): Promise<Node.ReadVResult>;
/**
* Creates a `ReadStream` for reading from the file.
*
* @param options Options for the readable stream
* @returns A `ReadStream` object.
*/
createReadStream(options?: CreateReadStreamOptions): ReadStream;
/**
* Creates a `WriteStream` for writing to the file.
*
* @param options Options for the writeable stream.
* @returns A `WriteStream` object
*/
createWriteStream(options?: CreateWriteStreamOptions): WriteStream;

@@ -244,3 +266,3 @@ }

/**
* Synchronously writes data to a file, replacing the file if it already exists.
* Asynchronously writes data to a file, replacing the file if it already exists.
*

@@ -381,7 +403,11 @@ * The encoding option is ignored if data is a buffer.

/**
* @todo Implement
* Asynchronous `rm`. Removes files or directories (recursively).
* @param path The path to the file or directory to remove.
*/
export declare function rm(path: PathLike, options?: Node.RmOptions): Promise<void>;
/**
* @todo Implement
* Asynchronous `mkdtemp`. Creates a unique temporary directory.
* @param prefix The directory prefix.
* @param options The encoding (or an object including `encoding`).
* @returns The path to the created temporary directory, encoded as a string or buffer.
*/

@@ -391,9 +417,28 @@ export declare function mkdtemp(prefix: string, options?: Node.EncodingOption): Promise<string>;

/**
* @todo Implement
* Asynchronous `copyFile`. Copies a file.
* @param src The source file.
* @param dest The destination file.
* @param mode Optional flags for the copy operation. Currently supports these flags:
* * `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
*/
export declare function copyFile(src: PathLike, dest: PathLike, mode?: number): Promise<void>;
/**
* @todo Implement
* Asynchronous `opendir`. Opens a directory.
* @param path The path to the directory.
* @param options Options for opening the directory.
* @returns A `Dir` object representing the opened directory.
*/
export declare function opendir(path: PathLike, options?: Node.OpenDirOptions): Promise<Dir>;
/**
* Asynchronous `cp`. Recursively copies a file or directory.
* @param source The source file or directory.
* @param destination The destination file or directory.
* @param opts Options for the copy operation. Currently supports these options from Node.js 'fs.await cp':
* * `dereference`: Dereference symbolic links.
* * `errorOnExist`: Throw an error if the destination file or directory already exists.
* * `filter`: A function that takes a source and destination path and returns a boolean, indicating whether to copy the given source element.
* * `force`: Overwrite the destination if it exists, and overwrite existing readonly destination files.
* * `preserveTimestamps`: Preserve file timestamps.
* * `recursive`: If `true`, copies directories recursively.
*/
export declare function cp(source: PathLike, destination: PathLike, opts?: Node.CopyOptions): Promise<void>;

@@ -411,1 +456,2 @@ /**

export declare function statfs(path: PathLike, opts?: Node.StatFsOptions): Promise<StatsFs | BigIntStatsFs>;
export declare function openAsBlob(path: PathLike, options?: Node.OpenAsBlobOptions): Promise<Blob>;

@@ -5,6 +5,8 @@ import { Buffer } from 'buffer';

import { BigIntStats, FileType } from '../stats.js';
import { F_OK } from './constants.js';
import { Dirent } from './dir.js';
import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
import * as constants from './constants.js';
import { Dir, Dirent } from './dir.js';
import { dirname, join, parse } from './path.js';
import { cred, fd2file, fdMap, fixError, getFdForFile, mounts, normalizeMode, normalizeOptions, normalizePath, normalizeTime, resolveMount } from './shared.js';
import { cred, fd2file, fdMap, fixError, getFdForFile, mounts, resolveMount } from './shared.js';
import { ReadStream, WriteStream } from './streams.js';
export * as constants from './constants.js';

@@ -19,8 +21,8 @@ export class FileHandle {

}
/**
* @internal
*/
get file() {
return fd2file(this.fd);
}
get path() {
return this.file.path;
}
/**

@@ -133,9 +135,31 @@ * Asynchronous fchown(2) - Change ownership of a file.

readableWebStream(options) {
throw ApiError.With('ENOTSUP', this.path, 'FileHandle.readableWebStream');
// Note: using an arrow function to preserve `this`
const start = async ({ close, enqueue, error }) => {
try {
const chunkSize = 64 * 1024, maxChunks = 1e7;
let i = 0, position = 0, result;
while (result.bytesRead > 0) {
result = await this.read(new Uint8Array(chunkSize), 0, chunkSize, position);
if (!result.bytesRead) {
close();
return;
}
enqueue(result.buffer.slice(0, result.bytesRead));
position += result.bytesRead;
if (++i >= maxChunks) {
throw new ApiError(ErrorCode.EFBIG, 'Too many iterations on readable stream', this.file.path, 'FileHandle.readableWebStream');
}
}
}
catch (e) {
error(e);
}
};
return new ReadableStream({ start, type: options.type });
}
readLines(options) {
throw ApiError.With('ENOTSUP', this.path, 'FileHandle.readLines');
throw ApiError.With('ENOSYS', this.file.path, 'FileHandle.readLines');
}
[Symbol.asyncDispose]() {
throw ApiError.With('ENOTSUP', this.path, 'FileHandle.@@asyncDispose');
return this.close();
}

@@ -197,22 +221,76 @@ async stat(opts) {

}
/* eslint-disable @typescript-eslint/no-unused-vars */
/**
* See `fs.writev` promisified version.
* @todo Implement
* Asynchronous `writev`. Writes from multiple buffers.
* @param buffers An array of Uint8Array buffers.
* @param position The position in the file where to begin writing.
* @returns The number of bytes written.
*/
writev(buffers, position) {
throw ApiError.With('ENOTSUP', this.path, 'FileHandle.writev');
async writev(buffers, position) {
let bytesWritten = 0;
for (const buffer of buffers) {
bytesWritten += (await this.write(buffer, 0, buffer.length, position + bytesWritten)).bytesWritten;
}
return { bytesWritten, buffers };
}
/**
* See `fs.readv` promisified version.
* @todo Implement
* Asynchronous `readv`. Reads into multiple buffers.
* @param buffers An array of Uint8Array buffers.
* @param position The position in the file where to begin reading.
* @returns The number of bytes read.
*/
readv(buffers, position) {
throw ApiError.With('ENOTSUP', this.path, 'FileHandle.readv');
async readv(buffers, position) {
let bytesRead = 0;
for (const buffer of buffers) {
bytesRead += (await this.read(buffer, 0, buffer.byteLength, position + bytesRead)).bytesRead;
}
return { bytesRead, buffers };
}
/**
* Creates a `ReadStream` for reading from the file.
*
* @param options Options for the readable stream
* @returns A `ReadStream` object.
*/
createReadStream(options) {
throw ApiError.With('ENOTSUP', this.path, 'createReadStream');
const streamOptions = {
highWaterMark: options?.highWaterMark || 64 * 1024,
encoding: options?.encoding,
read: async (size) => {
try {
const result = await this.read(new Uint8Array(size), 0, size, this.file.position);
stream.push(!result.bytesRead ? null : result.buffer.slice(0, result.bytesRead)); // Push data or null for EOF
this.file.position += result.bytesRead;
}
catch (error) {
stream.destroy(error);
}
},
};
const stream = new ReadStream(streamOptions);
stream.path = this.file.path;
return stream;
}
/**
* Creates a `WriteStream` for writing to the file.
*
* @param options Options for the writeable stream.
* @returns A `WriteStream` object
*/
createWriteStream(options) {
throw ApiError.With('ENOTSUP', this.path, 'createWriteStream');
const streamOptions = {
highWaterMark: options?.highWaterMark,
encoding: options?.encoding,
write: async (chunk, encoding, callback) => {
try {
const { bytesWritten } = await this.write(chunk, null, encoding);
callback(bytesWritten == chunk.length ? null : new Error('Failed to write full chunk'));
}
catch (error) {
callback(error);
}
},
};
const stream = new WriteStream(streamOptions);
stream.path = this.file.path;
return stream;
}

@@ -412,3 +490,3 @@ }

/**
* Synchronously writes data to a file, replacing the file if it already exists.
* Asynchronously writes data to a file, replacing the file if it already exists.
*

@@ -655,3 +733,3 @@ * The encoding option is ignored if data is a buffer.

export function watch(filename, options) {
throw ApiError.With('ENOTSUP', filename, 'watch');
throw ApiError.With('ENOSYS', filename, 'watch');
}

@@ -664,3 +742,3 @@ watch;

*/
export async function access(path, mode = F_OK) {
export async function access(path, mode = constants.F_OK) {
const stats = await stat(path);

@@ -672,35 +750,124 @@ if (!stats.hasAccess(mode, cred)) {

access;
/* eslint-disable @typescript-eslint/no-unused-vars */
/**
* @todo Implement
* Asynchronous `rm`. Removes files or directories (recursively).
* @param path The path to the file or directory to remove.
*/
export async function rm(path, options) {
throw ApiError.With('ENOTSUP', path, 'rm');
path = normalizePath(path);
const stats = await stat(path);
switch (stats.mode & constants.S_IFMT) {
case constants.S_IFDIR:
if (options?.recursive) {
for (const entry of await readdir(path)) {
await rm(join(path, entry));
}
}
await rmdir(path);
return;
case constants.S_IFREG:
case constants.S_IFLNK:
await unlink(path);
return;
case constants.S_IFBLK:
case constants.S_IFCHR:
case constants.S_IFIFO:
case constants.S_IFSOCK:
default:
throw new ApiError(ErrorCode.EPERM, 'File type not supported', path, 'rm');
}
}
rm;
export async function mkdtemp(prefix, options) {
throw ApiError.With('ENOTSUP', prefix, 'mkdtemp');
const encoding = typeof options === 'object' ? options.encoding : options || 'utf8';
const fsName = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}`;
const resolvedPath = '/tmp/' + fsName;
await mkdir(resolvedPath);
return encoding == 'buffer' ? Buffer.from(resolvedPath) : resolvedPath;
}
mkdtemp;
/**
* @todo Implement
* Asynchronous `copyFile`. Copies a file.
* @param src The source file.
* @param dest The destination file.
* @param mode Optional flags for the copy operation. Currently supports these flags:
* * `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
*/
export async function copyFile(src, dest, mode) {
throw ApiError.With('ENOTSUP', src, 'copyFile');
src = normalizePath(src);
dest = normalizePath(dest);
if (mode && mode & constants.COPYFILE_EXCL && (await exists(dest))) {
throw new ApiError(ErrorCode.EEXIST, 'Destination file already exists.', dest, 'copyFile');
}
await writeFile(dest, await readFile(src));
}
copyFile;
/**
* @todo Implement
* Asynchronous `opendir`. Opens a directory.
* @param path The path to the directory.
* @param options Options for opening the directory.
* @returns A `Dir` object representing the opened directory.
*/
export async function opendir(path, options) {
throw ApiError.With('ENOTSUP', path, 'opendir');
path = normalizePath(path);
return new Dir(path);
}
opendir;
/**
* Asynchronous `cp`. Recursively copies a file or directory.
* @param source The source file or directory.
* @param destination The destination file or directory.
* @param opts Options for the copy operation. Currently supports these options from Node.js 'fs.await cp':
* * `dereference`: Dereference symbolic links.
* * `errorOnExist`: Throw an error if the destination file or directory already exists.
* * `filter`: A function that takes a source and destination path and returns a boolean, indicating whether to copy the given source element.
* * `force`: Overwrite the destination if it exists, and overwrite existing readonly destination files.
* * `preserveTimestamps`: Preserve file timestamps.
* * `recursive`: If `true`, copies directories recursively.
*/
export async function cp(source, destination, opts) {
throw ApiError.With('ENOTSUP', source, 'cp');
source = normalizePath(source);
destination = normalizePath(destination);
const srcStats = await lstat(source); // Use lstat to follow symlinks if not dereferencing
if (opts?.errorOnExist && (await exists(destination))) {
throw new ApiError(ErrorCode.EEXIST, 'Destination file or directory already exists.', destination, 'cp');
}
switch (srcStats.mode & constants.S_IFMT) {
case constants.S_IFDIR:
if (!opts?.recursive) {
throw new ApiError(ErrorCode.EISDIR, source + ' is a directory (not copied)', source, 'cp');
}
await mkdir(destination, { recursive: true }); // Ensure the destination directory exists
for (const dirent of await readdir(source, { withFileTypes: true })) {
if (opts.filter && !opts.filter(join(source, dirent.name), join(destination, dirent.name))) {
continue; // Skip if the filter returns false
}
await cp(join(source, dirent.name), join(destination, dirent.name), opts);
}
break;
case constants.S_IFREG:
case constants.S_IFLNK:
await copyFile(source, destination);
break;
case constants.S_IFBLK:
case constants.S_IFCHR:
case constants.S_IFIFO:
case constants.S_IFSOCK:
default:
throw new ApiError(ErrorCode.EPERM, 'File type not supported', source, 'rm');
}
// Optionally preserve timestamps
if (opts?.preserveTimestamps) {
await utimes(destination, srcStats.atime, srcStats.mtime);
}
}
cp;
export async function statfs(path, opts) {
throw ApiError.With('ENOTSUP', path, 'statfs');
throw ApiError.With('ENOSYS', path, 'statfs');
}
/* eslint-enable @typescript-eslint/no-unused-vars */
export async function openAsBlob(path, options) {
const handle = await open(path, 'r');
const buffer = await handle.readFile();
await handle.close();
return new Blob([buffer], options);
}
openAsBlob;

@@ -1,49 +0,4 @@

/// <reference types="node" resolution-mode="require"/>
/// <reference types="node" resolution-mode="require"/>
import { Cred } from '../cred.js';
import type { File } from '../file.js';
import { FileSystem } from '../filesystem.js';
import type { File } from '../file.js';
import type { EncodingOption, OpenMode, WriteFileOptions } from 'node:fs';
/**
* converts Date or number to a integer UNIX timestamp
* Grabbed from NodeJS sources (lib/fs.js)
*
* @internal
*/
export declare function _toUnixTimestamp(time: Date | number): number;
/**
* Normalizes a mode
* @internal
*/
export declare function normalizeMode(mode: string | number | unknown, def?: number): number;
/**
* Normalizes a time
* @internal
*/
export declare function normalizeTime(time: string | number | Date): Date;
/**
* Normalizes a path
* @internal
*/
export declare function normalizePath(p: string): string;
/**
* Normalizes options
* @param options options to normalize
* @param encoding default encoding
* @param flag default flag
* @param mode default mode
* @internal
*/
export declare function normalizeOptions(options?: WriteFileOptions | (EncodingOption & {
flag?: OpenMode;
}), encoding?: BufferEncoding, flag?: string, mode?: number): {
encoding: BufferEncoding;
flag: string;
mode: number;
};
/**
* Do nothing
* @internal
*/
export declare function nop(): void;
export declare let cred: Cred;

@@ -50,0 +5,0 @@ export declare function setCred(val: Cred): void;

// Utilities and shared data
import { resolve } from './path.js';
import { ApiError, ErrorCode } from '../ApiError.js';
import { InMemory } from '../backends/InMemory.js';
import { rootCred } from '../cred.js';
import { InMemory } from '../backends/InMemory.js';
/**
* converts Date or number to a integer UNIX timestamp
* Grabbed from NodeJS sources (lib/fs.js)
*
* @internal
*/
export function _toUnixTimestamp(time) {
if (typeof time === 'number') {
return Math.floor(time);
}
if (time instanceof Date) {
return Math.floor(time.getTime() / 1000);
}
throw new Error('Cannot parse time: ' + time);
}
/**
* Normalizes a mode
* @internal
*/
export function normalizeMode(mode, def) {
if (typeof mode == 'number') {
return mode;
}
if (typeof mode == 'string') {
const parsed = parseInt(mode, 8);
if (!isNaN(parsed)) {
return parsed;
}
}
if (typeof def == 'number') {
return def;
}
throw new ApiError(ErrorCode.EINVAL, 'Invalid mode: ' + mode?.toString());
}
/**
* Normalizes a time
* @internal
*/
export function normalizeTime(time) {
if (time instanceof Date) {
return time;
}
if (typeof time == 'number') {
return new Date(time * 1000);
}
if (typeof time == 'string') {
return new Date(time);
}
throw new ApiError(ErrorCode.EINVAL, 'Invalid time.');
}
/**
* Normalizes a path
* @internal
*/
export function normalizePath(p) {
// Node doesn't allow null characters in paths.
if (p.includes('\x00')) {
throw new ApiError(ErrorCode.EINVAL, 'Path must be a string without null bytes.');
}
if (p.length == 0) {
throw new ApiError(ErrorCode.EINVAL, 'Path must not be empty.');
}
return resolve(p.replaceAll(/[/\\]+/g, '/'));
}
/**
* Normalizes options
* @param options options to normalize
* @param encoding default encoding
* @param flag default flag
* @param mode default mode
* @internal
*/
export function normalizeOptions(options, encoding = 'utf8', flag, mode = 0) {
if (typeof options != 'object' || options === null) {
return {
encoding: typeof options == 'string' ? options : encoding,
flag,
mode,
};
}
return {
encoding: typeof options?.encoding == 'string' ? options.encoding : encoding,
flag: typeof options?.flag == 'string' ? options.flag : flag,
mode: normalizeMode('mode' in options ? options?.mode : null, mode),
};
}
/**
* Do nothing
* @internal
*/
export function nop() {
// do nothing
}
import { normalizePath } from '../utils.js';
import { resolve } from './path.js';
// credentials

@@ -100,0 +8,0 @@ export let cred = rootCred;

@@ -300,7 +300,11 @@ /// <reference types="node" resolution-mode="require"/>

/**
* @todo Implement
* Synchronous `rm`. Removes files or directories (recursively).
* @param path The path to the file or directory to remove.
*/
export declare function rmSync(path: PathLike): void;
export declare function rmSync(path: PathLike, options?: Node.RmOptions): void;
/**
* @todo Implement
* Synchronous `mkdtemp`. Creates a unique temporary directory.
* @param prefix The directory prefix.
* @param options The encoding (or an object including `encoding`).
* @returns The path to the created temporary directory, encoded as a string or buffer.
*/

@@ -310,23 +314,47 @@ export declare function mkdtempSync(prefix: string, options: BufferEncodingOption): Buffer;

/**
* @todo Implement
* Synchronous `copyFile`. Copies a file.
* @param src The source file.
* @param dest The destination file.
* @param flags Optional flags for the copy operation. Currently supports these flags:
* * `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
*/
export declare function copyFileSync(src: string, dest: string, flags?: number): void;
export declare function copyFileSync(src: PathLike, dest: PathLike, flags?: number): void;
/**
* @todo Implement
* Synchronous `readv`. Reads from a file descriptor into multiple buffers.
* @param fd The file descriptor.
* @param buffers An array of Uint8Array buffers.
* @param position The position in the file where to begin reading.
* @returns The number of bytes read.
*/
export declare function readvSync(fd: number, buffers: readonly Uint8Array[], position?: number): number;
/**
* @todo Implement
* Synchronous `writev`. Writes from multiple buffers into a file descriptor.
* @param fd The file descriptor.
* @param buffers An array of Uint8Array buffers.
* @param position The position in the file where to begin writing.
* @returns The number of bytes written.
*/
export declare function writevSync(fd: number, buffers: readonly Uint8Array[], position?: number): number;
/**
* @todo Implement
* Synchronous `opendir`. Opens a directory.
* @param path The path to the directory.
* @param options Options for opening the directory.
* @returns A `Dir` object representing the opened directory.
*/
export declare function opendirSync(path: PathLike, options?: Node.OpenDirOptions): Dir;
/**
* @todo Implement
* Synchronous `cp`. Recursively copies a file or directory.
* @param source The source file or directory.
* @param destination The destination file or directory.
* @param opts Options for the copy operation. Currently supports these options from Node.js 'fs.cpSync':
* * `dereference`: Dereference symbolic links.
* * `errorOnExist`: Throw an error if the destination file or directory already exists.
* * `filter`: A function that takes a source and destination path and returns a boolean, indicating whether to copy the given source element.
* * `force`: Overwrite the destination if it exists, and overwrite existing readonly destination files.
* * `preserveTimestamps`: Preserve file timestamps.
* * `recursive`: If `true`, copies directories recursively.
*/
export declare function cpSync(source: PathLike, destination: PathLike, opts?: Node.CopySyncOptions): void;
/**
* Synchronous statfs(2). Returns information about the mounted file system which contains path. The callback gets two arguments (err, stats) where stats is an <fs.StatFs> object.
* Synchronous statfs(2). Returns information about the mounted file system which contains path.
* In case of an error, the err.code will be one of Common System Errors.

@@ -333,0 +361,0 @@ * @param path A path to an existing file or directory on the file system to be queried.

@@ -5,5 +5,7 @@ import { Buffer } from 'buffer';

import { BigIntStats, FileType } from '../stats.js';
import { Dirent } from './dir.js';
import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
import { COPYFILE_EXCL, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK } from './constants.js';
import { Dir, Dirent } from './dir.js';
import { dirname, join, parse } from './path.js';
import { cred, fd2file, fdMap, fixError, getFdForFile, mounts, normalizeMode, normalizeOptions, normalizePath, normalizeTime, resolveMount } from './shared.js';
import { cred, fd2file, fdMap, fixError, getFdForFile, mounts, resolveMount } from './shared.js';
function doOp(...[name, resolveSymlinks, path, ...args]) {

@@ -108,7 +110,7 @@ path = normalizePath(path);

if (!parentStats.isDirectory()) {
throw ApiError.With('ENOTDIR', dirname(path), '_openSync');
throw ApiError.With('ENOTDIR', dirname(path), '_open');
}
return doOp('createFileSync', resolveSymlinks, path, flag, mode, cred);
case ActionType.THROW:
throw ApiError.With('ENOENT', path, '_openSync');
throw ApiError.With('ENOENT', path, '_open');
default:

@@ -119,3 +121,3 @@ throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');

if (!stats.hasAccess(mode, cred)) {
throw ApiError.With('EACCES', path, '_openSync');
throw ApiError.With('EACCES', path, '_open');
}

@@ -125,3 +127,3 @@ // File exists.

case ActionType.THROW:
throw ApiError.With('EEXIST', path, '_openSync');
throw ApiError.With('EEXIST', path, '_open');
case ActionType.TRUNCATE:

@@ -433,3 +435,3 @@ // Delete file.

if (existsSync(path)) {
throw ApiError.With('EEXIST', path, 'symlinkSync');
throw ApiError.With('EEXIST', path, 'symlink');
}

@@ -550,52 +552,149 @@ writeFileSync(path, target);

accessSync;
/* eslint-disable @typescript-eslint/no-unused-vars */
/**
* @todo Implement
* Synchronous `rm`. Removes files or directories (recursively).
* @param path The path to the file or directory to remove.
*/
export function rmSync(path) {
throw ApiError.With('ENOTSUP', path, 'rmSync');
export function rmSync(path, options) {
path = normalizePath(path);
const stats = statSync(path);
switch (stats.mode & S_IFMT) {
case S_IFDIR:
if (options?.recursive) {
for (const entry of readdirSync(path)) {
rmSync(join(path, entry));
}
}
rmdirSync(path);
return;
case S_IFREG:
case S_IFLNK:
unlinkSync(path);
return;
case S_IFBLK:
case S_IFCHR:
case S_IFIFO:
case S_IFSOCK:
default:
throw new ApiError(ErrorCode.EPERM, 'File type not supported', path, 'rm');
}
}
rmSync;
export function mkdtempSync(prefix, options) {
throw ApiError.With('ENOTSUP', prefix, 'mkdtempSync');
const encoding = typeof options === 'object' ? options.encoding : options || 'utf8';
const fsName = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}`;
const resolvedPath = '/tmp/' + fsName;
mkdirSync(resolvedPath);
return encoding == 'buffer' ? Buffer.from(resolvedPath) : resolvedPath;
}
mkdtempSync;
/**
* @todo Implement
* Synchronous `copyFile`. Copies a file.
* @param src The source file.
* @param dest The destination file.
* @param flags Optional flags for the copy operation. Currently supports these flags:
* * `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
*/
export function copyFileSync(src, dest, flags) {
throw ApiError.With('ENOTSUP', src, 'copyFileSync');
src = normalizePath(src);
dest = normalizePath(dest);
if (flags && flags & COPYFILE_EXCL && existsSync(dest)) {
throw new ApiError(ErrorCode.EEXIST, 'Destination file already exists.', dest, 'copyFile');
}
writeFileSync(dest, readFileSync(src));
}
copyFileSync;
/**
* @todo Implement
* Synchronous `readv`. Reads from a file descriptor into multiple buffers.
* @param fd The file descriptor.
* @param buffers An array of Uint8Array buffers.
* @param position The position in the file where to begin reading.
* @returns The number of bytes read.
*/
export function readvSync(fd, buffers, position) {
throw ApiError.With('ENOTSUP', fd2file(fd).path, 'readvSync');
const file = fd2file(fd);
let bytesRead = 0;
for (const buffer of buffers) {
bytesRead += file.readSync(buffer, 0, buffer.length, position + bytesRead);
}
return bytesRead;
}
readvSync;
/**
* @todo Implement
* Synchronous `writev`. Writes from multiple buffers into a file descriptor.
* @param fd The file descriptor.
* @param buffers An array of Uint8Array buffers.
* @param position The position in the file where to begin writing.
* @returns The number of bytes written.
*/
export function writevSync(fd, buffers, position) {
throw ApiError.With('ENOTSUP', fd2file(fd).path, 'writevSync');
const file = fd2file(fd);
let bytesWritten = 0;
for (const buffer of buffers) {
bytesWritten += file.writeSync(buffer, 0, buffer.length, position + bytesWritten);
}
return bytesWritten;
}
writevSync;
/**
* @todo Implement
* Synchronous `opendir`. Opens a directory.
* @param path The path to the directory.
* @param options Options for opening the directory.
* @returns A `Dir` object representing the opened directory.
*/
export function opendirSync(path, options) {
throw ApiError.With('ENOTSUP', path, 'opendirSync');
path = normalizePath(path);
return new Dir(path); // Re-use existing `Dir` class
}
opendirSync;
/**
* @todo Implement
* Synchronous `cp`. Recursively copies a file or directory.
* @param source The source file or directory.
* @param destination The destination file or directory.
* @param opts Options for the copy operation. Currently supports these options from Node.js 'fs.cpSync':
* * `dereference`: Dereference symbolic links.
* * `errorOnExist`: Throw an error if the destination file or directory already exists.
* * `filter`: A function that takes a source and destination path and returns a boolean, indicating whether to copy the given source element.
* * `force`: Overwrite the destination if it exists, and overwrite existing readonly destination files.
* * `preserveTimestamps`: Preserve file timestamps.
* * `recursive`: If `true`, copies directories recursively.
*/
export function cpSync(source, destination, opts) {
throw ApiError.With('ENOTSUP', source, 'cpSync');
source = normalizePath(source);
destination = normalizePath(destination);
const srcStats = lstatSync(source); // Use lstat to follow symlinks if not dereferencing
if (opts?.errorOnExist && existsSync(destination)) {
throw new ApiError(ErrorCode.EEXIST, 'Destination file or directory already exists.', destination, 'cp');
}
switch (srcStats.mode & S_IFMT) {
case S_IFDIR:
if (!opts?.recursive) {
throw new ApiError(ErrorCode.EISDIR, source + ' is a directory (not copied)', source, 'cp');
}
mkdirSync(destination, { recursive: true }); // Ensure the destination directory exists
for (const dirent of readdirSync(source, { withFileTypes: true })) {
if (opts.filter && !opts.filter(join(source, dirent.name), join(destination, dirent.name))) {
continue; // Skip if the filter returns false
}
cpSync(join(source, dirent.name), join(destination, dirent.name), opts);
}
break;
case S_IFREG:
case S_IFLNK:
copyFileSync(source, destination);
break;
case S_IFBLK:
case S_IFCHR:
case S_IFIFO:
case S_IFSOCK:
default:
throw new ApiError(ErrorCode.EPERM, 'File type not supported', source, 'rm');
}
// Optionally preserve timestamps
if (opts?.preserveTimestamps) {
utimesSync(destination, srcStats.atime, srcStats.mtime);
}
}
cpSync;
export function statfsSync(path, options) {
throw ApiError.With('ENOTSUP', path, 'statfsSync');
throw ApiError.With('ENOSYS', path, 'statfs');
}
/* eslint-enable @typescript-eslint/no-unused-vars */

@@ -223,3 +223,6 @@ import { type Cred } from './cred.js';

}
/**
* Implements the non-readonly methods to throw `EROFS`
*/
export declare function Readonly<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => ReadonlyFileSystem) & T;
export {};

@@ -27,3 +27,2 @@ import { ApiError, ErrorCode } from './ApiError.js';

}
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
constructor(options) {

@@ -61,5 +60,2 @@ // unused

export function Sync(FS) {
/**
* Implements the asynchronous API in terms of the synchronous API.
*/
class _SyncFileSystem extends FS {

@@ -244,2 +240,5 @@ async ready() {

}
/**
* Implements the non-readonly methods to throw `EROFS`
*/
export function Readonly(FS) {

@@ -246,0 +245,0 @@ class _ReadonlyFileSystem extends FS {

@@ -12,3 +12,3 @@ export * from './backends/backend.js';

export * from './filesystem.js';
export * from './FileIndex.js';
export * from './backends/FileIndex.js';
export * from './inode.js';

@@ -15,0 +15,0 @@ export * from './mutex.js';

@@ -12,3 +12,3 @@ export * from './backends/backend.js';

export * from './filesystem.js';
export * from './FileIndex.js';
export * from './backends/FileIndex.js';
export * from './inode.js';

@@ -15,0 +15,0 @@ export * from './mutex.js';

@@ -0,1 +1,3 @@

/// <reference types="node" resolution-mode="require"/>
/// <reference types="node" resolution-mode="require"/>
import type { OptionalTuple } from 'utilium';

@@ -44,1 +46,44 @@ import { ApiError } from './ApiError.js';

export type Callback<Args extends unknown[] = []> = (e?: ApiError, ...args: OptionalTuple<Args>) => unknown;
import type { EncodingOption, OpenMode, WriteFileOptions } from 'node:fs';
/**
* converts Date or number to a integer UNIX timestamp
* Grabbed from NodeJS sources (lib/fs.js)
*
* @internal
*/
export declare function _toUnixTimestamp(time: Date | number): number;
/**
* Normalizes a mode
* @internal
*/
export declare function normalizeMode(mode: string | number | unknown, def?: number): number;
/**
* Normalizes a time
* @internal
*/
export declare function normalizeTime(time: string | number | Date): Date;
/**
* Normalizes a path
* @internal
*/
export declare function normalizePath(p: string): string;
/**
* Normalizes options
* @param options options to normalize
* @param encoding default encoding
* @param flag default flag
* @param mode default mode
* @internal
*/
export declare function normalizeOptions(options?: WriteFileOptions | (EncodingOption & {
flag?: OpenMode;
}), encoding?: BufferEncoding, flag?: string, mode?: number): {
encoding: BufferEncoding;
flag: string;
mode: number;
};
/**
* Do nothing
* @internal
*/
export declare function nop(): void;
import { ApiError, ErrorCode } from './ApiError.js';
import { dirname } from './emulation/path.js';
import { dirname, resolve } from './emulation/path.js';
/**

@@ -136,1 +136,94 @@ * Synchronous recursive makedir.

}
/**
* converts Date or number to a integer UNIX timestamp
* Grabbed from NodeJS sources (lib/fs.js)
*
* @internal
*/
export function _toUnixTimestamp(time) {
if (typeof time === 'number') {
return Math.floor(time);
}
if (time instanceof Date) {
return Math.floor(time.getTime() / 1000);
}
throw new Error('Cannot parse time: ' + time);
}
/**
* Normalizes a mode
* @internal
*/
export function normalizeMode(mode, def) {
if (typeof mode == 'number') {
return mode;
}
if (typeof mode == 'string') {
const parsed = parseInt(mode, 8);
if (!isNaN(parsed)) {
return parsed;
}
}
if (typeof def == 'number') {
return def;
}
throw new ApiError(ErrorCode.EINVAL, 'Invalid mode: ' + mode?.toString());
}
/**
* Normalizes a time
* @internal
*/
export function normalizeTime(time) {
if (time instanceof Date) {
return time;
}
if (typeof time == 'number') {
return new Date(time * 1000);
}
if (typeof time == 'string') {
return new Date(time);
}
throw new ApiError(ErrorCode.EINVAL, 'Invalid time.');
}
/**
* Normalizes a path
* @internal
*/
export function normalizePath(p) {
// Node doesn't allow null characters in paths.
if (p.includes('\x00')) {
throw new ApiError(ErrorCode.EINVAL, 'Path must be a string without null bytes.');
}
if (p.length == 0) {
throw new ApiError(ErrorCode.EINVAL, 'Path must not be empty.');
}
return resolve(p.replaceAll(/[/\\]+/g, '/'));
}
/**
* Normalizes options
* @param options options to normalize
* @param encoding default encoding
* @param flag default flag
* @param mode default mode
* @internal
*/
export function normalizeOptions(options, encoding = 'utf8', flag, mode = 0) {
if (typeof options != 'object' || options === null) {
return {
encoding: typeof options == 'string' ? options : encoding,
flag,
mode,
};
}
return {
encoding: typeof options?.encoding == 'string' ? options.encoding : encoding,
flag: typeof options?.flag == 'string' ? options.flag : flag,
mode: normalizeMode('mode' in options ? options?.mode : null, mode),
};
}
/**
* Do nothing
* @internal
*/
export function nop() {
// do nothing
}
{
"name": "@zenfs/core",
"version": "0.8.1",
"version": "0.9.0",
"description": "A filesystem in your browser",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc