Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@zenfs/core

Package Overview
Dependencies
Maintainers
1
Versions
156
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.3.5 to 0.4.0

scripts/make-index.js

8

dist/backends/AsyncMirror.d.ts
import { FileSystem, FileSystemMetadata } from '../filesystem.js';
import { File, FileFlag, PreloadFile } from '../file.js';
import { Stats } from '../stats.js';
import type { Stats } from '../stats.js';
import { Cred } from '../cred.js';

@@ -8,4 +8,5 @@ import type { Backend } from './backend.js';

* We define our own file to interpose on syncSync() for mirroring purposes.
* @internal
*/
declare class MirrorFile extends PreloadFile<AsyncMirrorFS> {
export declare class MirrorFile extends PreloadFile<AsyncMirrorFS> {
constructor(fs: AsyncMirrorFS, path: string, flag: FileFlag, stat: Stats, data: Uint8Array);

@@ -45,5 +46,2 @@ sync(): Promise<void>;

renameSync(oldPath: string, newPath: string, cred: Cred): void;
/**
* Queue of pending asynchronous operations.
*/
statSync(path: string, cred: Cred): Stats;

@@ -50,0 +48,0 @@ openFileSync(path: string, flag: FileFlag, cred: Cred): File;

@@ -8,4 +8,5 @@ import { FileSystem, Sync } from '../filesystem.js';

* We define our own file to interpose on syncSync() for mirroring purposes.
* @internal
*/
class MirrorFile extends PreloadFile {
export class MirrorFile extends PreloadFile {
constructor(fs, path, flag, stat, data) {

@@ -157,4 +158,4 @@ super(fs, path, flag, stat, data);

async crossCopyFile(p, mode) {
const asyncFile = await this._async.openFile(p, FileFlag.FromString('r'), Cred.Root);
const syncFile = this._sync.createFileSync(p, FileFlag.FromString('w'), mode, Cred.Root);
const asyncFile = await this._async.openFile(p, FileFlag.Get('r'), Cred.Root);
const syncFile = this._sync.createFileSync(p, FileFlag.Get('w'), mode, Cred.Root);
try {

@@ -235,5 +236,5 @@ const { size } = await asyncFile.stat();

description: 'The synchronous file system to mirror the asynchronous file system to.',
validator: async (v) => {
if (!v?.metadata().synchronous) {
throw new ApiError(ErrorCode.EINVAL, `'sync' option must be a file system that supports synchronous operations`);
validator: async (backend) => {
if ('metadata' in backend && !backend.metadata().synchronous) {
throw new ApiError(ErrorCode.EINVAL, '"sync" option must be a file system that supports synchronous operations');
}

@@ -240,0 +241,0 @@ },

@@ -1,6 +0,6 @@

import { Cred } from '../cred.js';
import type { Cred } from '../cred.js';
import { PreloadFile, File, FileFlag } from '../file.js';
import { FileSystem, type FileSystemMetadata } from '../filesystem.js';
import { type Ino } from '../inode.js';
import { Stats } from '../stats.js';
import { type Stats } from '../stats.js';
/**

@@ -65,2 +65,6 @@ * Represents an *asynchronous* key-value store.

}
/**
* Async preload file for usage with AsyncStore
* @internal
*/
export declare class AsyncFile extends PreloadFile<AsyncStoreFS> {

@@ -97,4 +101,5 @@ constructor(_fs: AsyncStoreFS, _path: string, _flag: FileFlag, _stat: Stats, contents?: Uint8Array);

/**
* An "Asynchronous key-value file system". Stores data to/retrieves data from
* an underlying asynchronous key-value store.
* An asynchronous file system which uses an async store to store its data.
* @see AsyncStore
* @internal
*/

@@ -101,0 +106,0 @@ export declare class AsyncStoreFS extends AsyncStoreFS_base {

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

}
/**
* Async preload file for usage with AsyncStore
* @internal
*/
export class AsyncFile extends PreloadFile {

@@ -70,4 +74,5 @@ constructor(_fs, _path, _flag, _stat, contents) {

/**
* An "Asynchronous key-value file system". Stores data to/retrieves data from
* an underlying asynchronous key-value store.
* An asynchronous file system which uses an async store to store its data.
* @see AsyncStore
* @internal
*/

@@ -74,0 +79,0 @@ export class AsyncStoreFS extends Async(FileSystem) {

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

for (const [optName, opt] of Object.entries(backend.options)) {
const providedValue = opts && opt;
const providedValue = opts?.[optName];
if (providedValue === undefined || providedValue === null) {

@@ -40,3 +40,3 @@ if (!opt.required) {

if (!typeMatches) {
throw new ApiError(ErrorCode.EINVAL, `${backend.name}: Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}\nOption description: ${opt.description}`);
throw new ApiError(ErrorCode.EINVAL, `${backend.name}: Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}`);
}

@@ -65,9 +65,9 @@ if (opt.validator) {

export async function resolveBackendConfig(options) {
const { backend } = options;
if (!backend) {
throw new ApiError(ErrorCode.EPERM, 'Missing backend');
}
if (typeof options !== 'object' || options == null) {
throw new ApiError(ErrorCode.EINVAL, 'Invalid options on configuration object.');
}
const { backend } = options;
if (!isBackend(backend)) {
throw new ApiError(ErrorCode.EINVAL, 'Missing or invalid backend');
}
const props = Object.keys(options).filter(k => k != 'backend');

@@ -83,4 +83,4 @@ for (const prop of props) {

}
if (!backend) {
throw new ApiError(ErrorCode.EPERM, `Backend "${backend}" is not available`);
if (!backend.isAvailable()) {
throw new ApiError(ErrorCode.EPERM, 'Backend not available: ' + backend);
}

@@ -87,0 +87,0 @@ checkOptions(backend, options);

@@ -1,6 +0,5 @@

import { FileSystem, FileSystemMetadata } from '../filesystem.js';
import { FileFlag } from '../file.js';
import { Stats } from '../stats.js';
import { File } from '../file.js';
import { Cred } from '../cred.js';
import type { Cred } from '../cred.js';
import type { File, FileFlag } from '../file.js';
import type { FileSystem, FileSystemMetadata } from '../filesystem.js';
import type { Stats } from '../stats.js';
/**

@@ -14,7 +13,8 @@ * This class serializes access to an underlying async filesystem.

* multiple requests interleaving.
* @internal
*/
export declare class LockedFS<T extends FileSystem> implements FileSystem {
readonly fs: T;
export declare class LockedFS<FS extends FileSystem> implements FileSystem {
readonly fs: FS;
private _mu;
constructor(fs: T);
constructor(fs: FS);
ready(): Promise<this>;

@@ -21,0 +21,0 @@ metadata(): FileSystemMetadata;

@@ -1,2 +0,2 @@

import Mutex from '../mutex.js';
import { Mutex } from '../mutex.js';
/**

@@ -10,2 +10,3 @@ * This class serializes access to an underlying async filesystem.

* multiple requests interleaving.
* @internal
*/

@@ -12,0 +13,0 @@ export class LockedFS {

import { FileSystem, FileSystemMetadata } from '../filesystem.js';
import { File, FileFlag } from '../file.js';
import { File, FileFlag, PreloadFile } from '../file.js';
import { Stats } from '../stats.js';

@@ -8,2 +8,13 @@ import { LockedFS } from './Locked.js';

/**
* Overlays a RO file to make it writable.
* @internal
*/
export declare class OverlayFile extends PreloadFile<UnlockedOverlayFS> implements File {
constructor(fs: UnlockedOverlayFS, path: string, flag: FileFlag, stats: Stats, data: Uint8Array);
sync(): Promise<void>;
syncSync(): void;
close(): Promise<void>;
closeSync(): void;
}
/**
* Configuration options for OverlayFS instances.

@@ -99,2 +110,3 @@ */

* file system.
* @internal
*/

@@ -101,0 +113,0 @@ export declare class OverlayFS extends LockedFS<UnlockedOverlayFS> {

@@ -15,4 +15,5 @@ import { FileSystem } from '../filesystem.js';

* Overlays a RO file to make it writable.
* @internal
*/
class OverlayFile extends PreloadFile {
export class OverlayFile extends PreloadFile {
constructor(fs, path, flag, stats, data) {

@@ -107,3 +108,3 @@ super(fs, path, flag, stats, data);

try {
const file = await this._writable.openFile(deletionLogPath, FileFlag.FromString('r'), Cred.Root);
const file = await this._writable.openFile(deletionLogPath, FileFlag.Get('r'), Cred.Root);
const { size } = await file.stat();

@@ -164,5 +165,4 @@ const { buffer } = await file.read(new Uint8Array(size));

}
const oldStat = Stats.clone(await this._readable.stat(p, cred));
// Make the oldStat's mode writable. Preserve the topmost part of the
// mode, which specifies if it is a file or a directory.
const oldStat = new Stats(await this._readable.stat(p, cred));
// Make the oldStat's mode writable. Preserve the topmost part of the mode, which specifies the type
oldStat.mode |= 0o222;

@@ -181,5 +181,4 @@ return oldStat;

}
const oldStat = Stats.clone(this._readable.statSync(p, cred));
// Make the oldStat's mode writable. Preserve the topmost part of the
// mode, which specifies if it is a file or a directory.
const oldStat = new Stats(this._readable.statSync(p, cred));
// Make the oldStat's mode writable. Preserve the topmost part of the mode, which specifies the type.
oldStat.mode |= 0o222;

@@ -194,4 +193,4 @@ return oldStat;

// Create an OverlayFile.
const file = await this._readable.openFile(path, FileFlag.FromString('r'), cred);
const stats = Stats.clone(await file.stat());
const file = await this._readable.openFile(path, FileFlag.Get('r'), cred);
const stats = new Stats(await file.stat());
const { buffer } = await file.read(new Uint8Array(stats.size));

@@ -205,3 +204,3 @@ return new OverlayFile(this, path, flag, stats, buffer);

// Create an OverlayFile.
const file = this._readable.openFileSync(path, FileFlag.FromString('r'), cred);
const file = this._readable.openFileSync(path, FileFlag.Get('r'), cred);
const stats = Stats.clone(file.statSync());

@@ -377,3 +376,3 @@ const data = new Uint8Array(stats.size);

this._deleteLogUpdatePending = true;
const log = await this._writable.openFile(deletionLogPath, FileFlag.FromString('w'), cred);
const log = await this._writable.openFile(deletionLogPath, FileFlag.Get('w'), cred);
try {

@@ -480,6 +479,6 @@ await log.write(encode(this._deleteLog));

const data = new Uint8Array(stats.size);
const readable = this._readable.openFileSync(p, FileFlag.FromString('r'), cred);
const readable = this._readable.openFileSync(p, FileFlag.Get('r'), cred);
readable.readSync(data);
readable.closeSync();
const writable = this._writable.openFileSync(p, FileFlag.FromString('w'), cred);
const writable = this._writable.openFileSync(p, FileFlag.Get('w'), cred);
writable.writeSync(data);

@@ -495,6 +494,6 @@ writable.closeSync();

const data = new Uint8Array(stats.size);
const readable = await this._readable.openFile(p, FileFlag.FromString('r'), cred);
const readable = await this._readable.openFile(p, FileFlag.Get('r'), cred);
await readable.read(data);
await readable.close();
const writable = await this._writable.openFile(p, FileFlag.FromString('w'), cred);
const writable = await this._writable.openFile(p, FileFlag.Get('w'), cred);
await writable.write(data);

@@ -508,2 +507,3 @@ await writable.close();

* file system.
* @internal
*/

@@ -510,0 +510,0 @@ export class OverlayFS extends LockedFS {

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

import { type Ino, Inode } from '../inode.js';
import { Stats, FileType } from '../stats.js';
import { type Stats, FileType } from '../stats.js';
/**

@@ -116,2 +116,6 @@ * Represents a *synchronous* key-value store.

}
/**
* File backend by a SyncStoreFS
* @internal
*/
export declare class SyncStoreFile extends PreloadFile<SyncStoreFS> {

@@ -151,9 +155,8 @@ constructor(_fs: SyncStoreFS, _path: string, _flag: FileFlag, _stat: Stats, contents?: Uint8Array);

/**
* A "Synchronous key-value file system". Stores data to/retrieves data from an
* underlying key-value store.
* A synchronous key-value file system. Uses a SyncStore to store the data.
*
* We use a unique ID for each node in the file system. The root node has a
* fixed ID.
* We use a unique ID for each node in the file system. The root node has a fixed ID.
* @todo Introduce Node ID caching.
* @todo Check modes.
* @internal
*/

@@ -160,0 +163,0 @@ export declare class SyncStoreFS extends SyncStoreFS_base {

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

}
/**
* File backend by a SyncStoreFS
* @internal
*/
export class SyncStoreFile extends PreloadFile {

@@ -101,9 +105,8 @@ constructor(_fs, _path, _flag, _stat, contents) {

/**
* A "Synchronous key-value file system". Stores data to/retrieves data from an
* underlying key-value store.
* A synchronous key-value file system. Uses a SyncStore to store the data.
*
* We use a unique ID for each node in the file system. The root node has a
* fixed ID.
* We use a unique ID for each node in the file system. The root node has a fixed ID.
* @todo Introduce Node ID caching.
* @todo Check modes.
* @internal
*/

@@ -352,3 +355,4 @@ export class SyncStoreFS extends Sync(FileSystem) {

}
return new Inode(data.buffer);
const inode = new Inode(data.buffer);
return inode;
}

@@ -355,0 +359,0 @@ /**

/**
* Credentials used for FS ops.
* Credentials used for various operations.
* Similar to Linux's cred struct. See https://github.com/torvalds/linux/blob/master/include/linux/cred.h

@@ -4,0 +4,0 @@ */

/**
* Credentials used for FS ops.
* Credentials used for various operations.
* Similar to Linux's cred struct. See https://github.com/torvalds/linux/blob/master/include/linux/cred.h

@@ -4,0 +4,0 @@ */

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

import { TwoArgCallback, NoArgCallback, ThreeArgCallback, FileContents } from '../filesystem.js';
import { BigIntStats, Stats } from '../stats.js';
import { BigIntStats, type Stats } from '../stats.js';
import { PathLike } from './shared.js';

@@ -8,0 +8,0 @@ import { ReadStream, WriteStream } from './streams.js';

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

.stat()
.then(stats => cb(null, (typeof options == 'object' && options?.bigint ? BigIntStats.clone(stats) : stats)))
.then(stats => cb(null, (typeof options == 'object' && options?.bigint ? new BigIntStats(stats) : stats)))
.catch(cb);

@@ -108,0 +108,0 @@ }

@@ -1,8 +0,8 @@

/** Constant for fs.access(). File is visible to the calling process. */
/** File is visible to the calling process. */
export declare const F_OK = 0;
/** Constant for fs.access(). File can be read by the calling process. */
/** File can be read by the calling process. */
export declare const R_OK = 4;
/** Constant for fs.access(). File can be written by the calling process. */
/** File can be written by the calling process. */
export declare const W_OK = 2;
/** Constant for fs.access(). File can be executed by the calling process. */
/** File can be executed by the calling process. */
export declare const X_OK = 1;

@@ -21,14 +21,14 @@ /** Constant for fs.copyFile. Flag indicating the destination file should not be overwritten if it already exists. */

export declare const COPYFILE_FICLONE_FORCE = 4;
/** Constant for fs.open(). Flag indicating to open a file for read-only access. */
/** Flag indicating to open a file for read-only access. */
export declare const O_RDONLY = 0;
/** Constant for fs.open(). Flag indicating to open a file for write-only access. */
/** Flag indicating to open a file for write-only access. */
export declare const O_WRONLY = 1;
/** Constant for fs.open(). Flag indicating to open a file for read-write access. */
/** Flag indicating to open a file for read-write access. */
export declare const O_RDWR = 2;
/** Constant for fs.open(). Flag indicating to create the file if it does not already exist. */
/** Flag indicating to create the file if it does not already exist. */
export declare const O_CREAT = 64;
/** Constant for fs.open(). Flag indicating that opening a file should fail if the O_CREAT flag is set and the file already exists. */
/** Flag indicating that opening a file should fail if the O_CREAT flag is set and the file already exists. */
export declare const O_EXCL = 128;
/**
* Constant for fs.open(). Flag indicating that if path identifies a terminal device,
* Flag indicating that if path identifies a terminal device,
* opening the path shall not cause that terminal to become the controlling terminal for the process

@@ -38,7 +38,7 @@ * (if the process does not already have one).

export declare const O_NOCTTY = 256;
/** Constant for fs.open(). Flag indicating that if the file exists and is a regular file, and the file is opened successfully for write access, its length shall be truncated to zero. */
/** Flag indicating that if the file exists and is a regular file, and the file is opened successfully for write access, its length shall be truncated to zero. */
export declare const O_TRUNC = 512;
/** Constant for fs.open(). Flag indicating that data will be appended to the end of the file. */
/** Flag indicating that data will be appended to the end of the file. */
export declare const O_APPEND = 1024;
/** Constant for fs.open(). Flag indicating that the open should fail if the path is not a directory. */
/** Flag indicating that the open should fail if the path is not a directory. */
export declare const O_DIRECTORY = 65536;

@@ -52,53 +52,59 @@ /**

export declare const O_NOATIME = 262144;
/** Constant for fs.open(). Flag indicating that the open should fail if the path is a symbolic link. */
/** Flag indicating that the open should fail if the path is a symbolic link. */
export declare const O_NOFOLLOW = 131072;
/** Constant for fs.open(). Flag indicating that the file is opened for synchronous I/O. */
/** Flag indicating that the file is opened for synchronous I/O. */
export declare const O_SYNC = 1052672;
/** Constant for fs.open(). Flag indicating that the file is opened for synchronous I/O with write operations waiting for data integrity. */
/** Flag indicating that the file is opened for synchronous I/O with write operations waiting for data integrity. */
export declare const O_DSYNC = 4096;
/** Constant for fs.open(). Flag indicating to open the symbolic link itself rather than the resource it is pointing to. */
/** Flag indicating to open the symbolic link itself rather than the resource it is pointing to. */
export declare const O_SYMLINK = 32768;
/** Constant for fs.open(). When set, an attempt will be made to minimize caching effects of file I/O. */
/** When set, an attempt will be made to minimize caching effects of file I/O. */
export declare const O_DIRECT = 16384;
/** Constant for fs.open(). Flag indicating to open the file in nonblocking mode when possible. */
/** Flag indicating to open the file in nonblocking mode when possible. */
export declare const O_NONBLOCK = 2048;
/** Constant for fs.Stats mode property for determining a file's type. Bit mask used to extract the file type code. */
/** Bit mask used to extract the file type from mode. */
export declare const S_IFMT = 61440;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a regular file. */
/** File type constant for a socket. */
export declare const S_IFSOCK = 49152;
/** File type constant for a symbolic link. */
export declare const S_IFLNK = 40960;
/** File type constant for a regular file. */
export declare const S_IFREG = 32768;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a directory. */
/** File type constant for a block-oriented device file. */
export declare const S_IFBLK = 24576;
/** File type constant for a directory. */
export declare const S_IFDIR = 16384;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a character-oriented device file. */
/** File type constant for a character-oriented device file. */
export declare const S_IFCHR = 8192;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a block-oriented device file. */
export declare const S_IFBLK = 24576;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a FIFO/pipe. */
/** File type constant for a FIFO/pipe. */
export declare const S_IFIFO = 4096;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a symbolic link. */
export declare const S_IFLNK = 40960;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a socket. */
export declare const S_IFSOCK = 49152;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by owner. */
/** Set user id */
export declare const S_ISUID = 2048;
/** Set group id */
export declare const S_ISGID = 1024;
/** Sticky bit */
export declare const S_ISVTX = 512;
/** File mode indicating readable, writable and executable by owner. */
export declare const S_IRWXU = 448;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by owner. */
/** File mode indicating readable by owner. */
export declare const S_IRUSR = 256;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by owner. */
/** File mode indicating writable by owner. */
export declare const S_IWUSR = 128;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by owner. */
/** File mode indicating executable by owner. */
export declare const S_IXUSR = 64;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by group. */
/** File mode indicating readable, writable and executable by group. */
export declare const S_IRWXG = 56;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by group. */
/** File mode indicating readable by group. */
export declare const S_IRGRP = 32;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by group. */
/** File mode indicating writable by group. */
export declare const S_IWGRP = 16;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by group. */
/** File mode indicating executable by group. */
export declare const S_IXGRP = 8;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by others. */
/** File mode indicating readable, writable and executable by others. */
export declare const S_IRWXO = 7;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by others. */
/** File mode indicating readable by others. */
export declare const S_IROTH = 4;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by others. */
/** File mode indicating writable by others. */
export declare const S_IWOTH = 2;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by others. */
/** File mode indicating executable by others. */
export declare const S_IXOTH = 1;
/*
FS Constants
See https://nodejs.org/api/fs.html#file-access-constants
Note: Many of these are pulled from
https://github.com/torvalds/linux/blob/master/include/uapi/linux/stat.h
*/
// File Access Constants
/** Constant for fs.access(). File is visible to the calling process. */
/** File is visible to the calling process. */
export const F_OK = 0;
/** Constant for fs.access(). File can be read by the calling process. */
/** File can be read by the calling process. */
export const R_OK = 4;
/** Constant for fs.access(). File can be written by the calling process. */
/** File can be written by the calling process. */
export const W_OK = 2;
/** Constant for fs.access(). File can be executed by the calling process. */
/** File can be executed by the calling process. */
export const X_OK = 1;

@@ -28,24 +31,24 @@ // File Copy Constants

// File Open Constants
/** Constant for fs.open(). Flag indicating to open a file for read-only access. */
/** Flag indicating to open a file for read-only access. */
export const O_RDONLY = 0;
/** Constant for fs.open(). Flag indicating to open a file for write-only access. */
/** Flag indicating to open a file for write-only access. */
export const O_WRONLY = 1;
/** Constant for fs.open(). Flag indicating to open a file for read-write access. */
/** Flag indicating to open a file for read-write access. */
export const O_RDWR = 2;
/** Constant for fs.open(). Flag indicating to create the file if it does not already exist. */
export const O_CREAT = 0o100; // Node internal is
/** Constant for fs.open(). Flag indicating that opening a file should fail if the O_CREAT flag is set and the file already exists. */
export const O_EXCL = 0o200;
/** Flag indicating to create the file if it does not already exist. */
export const O_CREAT = 0x40; // bit 6
/** Flag indicating that opening a file should fail if the O_CREAT flag is set and the file already exists. */
export const O_EXCL = 0x80; // bit 7
/**
* Constant for fs.open(). Flag indicating that if path identifies a terminal device,
* Flag indicating that if path identifies a terminal device,
* opening the path shall not cause that terminal to become the controlling terminal for the process
* (if the process does not already have one).
*/
export const O_NOCTTY = 0o400;
/** Constant for fs.open(). Flag indicating that if the file exists and is a regular file, and the file is opened successfully for write access, its length shall be truncated to zero. */
export const O_TRUNC = 0o1000;
/** Constant for fs.open(). Flag indicating that data will be appended to the end of the file. */
export const O_APPEND = 0o2000;
/** Constant for fs.open(). Flag indicating that the open should fail if the path is not a directory. */
export const O_DIRECTORY = 0o200000;
export const O_NOCTTY = 0x100; // bit 8
/** Flag indicating that if the file exists and is a regular file, and the file is opened successfully for write access, its length shall be truncated to zero. */
export const O_TRUNC = 0x200; // bit 9
/** Flag indicating that data will be appended to the end of the file. */
export const O_APPEND = 0x400; // bit 10
/** Flag indicating that the open should fail if the path is not a directory. */
export const O_DIRECTORY = 0x10000; // bit 16
/**

@@ -57,56 +60,62 @@ * constant for fs.open().

*/
export const O_NOATIME = 0o1000000;
/** Constant for fs.open(). Flag indicating that the open should fail if the path is a symbolic link. */
export const O_NOFOLLOW = 0o400000;
/** Constant for fs.open(). Flag indicating that the file is opened for synchronous I/O. */
export const O_SYNC = 0o4010000;
/** Constant for fs.open(). Flag indicating that the file is opened for synchronous I/O with write operations waiting for data integrity. */
export const O_DSYNC = 0o10000;
/** Constant for fs.open(). Flag indicating to open the symbolic link itself rather than the resource it is pointing to. */
export const O_SYMLINK = 0o100000;
/** Constant for fs.open(). When set, an attempt will be made to minimize caching effects of file I/O. */
export const O_DIRECT = 0o40000;
/** Constant for fs.open(). Flag indicating to open the file in nonblocking mode when possible. */
export const O_NONBLOCK = 0o4000;
export const O_NOATIME = 0x40000; // bit 18
/** Flag indicating that the open should fail if the path is a symbolic link. */
export const O_NOFOLLOW = 0x20000; // bit 17
/** Flag indicating that the file is opened for synchronous I/O. */
export const O_SYNC = 0x101000; // bit 20 and bit 12
/** Flag indicating that the file is opened for synchronous I/O with write operations waiting for data integrity. */
export const O_DSYNC = 0x1000; // bit 12
/** Flag indicating to open the symbolic link itself rather than the resource it is pointing to. */
export const O_SYMLINK = 0x8000; // bit 15
/** When set, an attempt will be made to minimize caching effects of file I/O. */
export const O_DIRECT = 0x4000; // bit 14
/** Flag indicating to open the file in nonblocking mode when possible. */
export const O_NONBLOCK = 0x800; // bit 11
// File Type Constants
/** Constant for fs.Stats mode property for determining a file's type. Bit mask used to extract the file type code. */
/** Bit mask used to extract the file type from mode. */
export const S_IFMT = 0xf000;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a regular file. */
export const S_IFREG = 0o100000;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a directory. */
export const S_IFDIR = 0o40000;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a character-oriented device file. */
export const S_IFCHR = 0o20000;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a block-oriented device file. */
export const S_IFBLK = 0o60000;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a FIFO/pipe. */
export const S_IFIFO = 0o10000;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a symbolic link. */
export const S_IFLNK = 0o120000;
/** Constant for fs.Stats mode property for determining a file's type. File type constant for a socket. */
export const S_IFSOCK = 0o140000;
/** File type constant for a socket. */
export const S_IFSOCK = 0xc000;
/** File type constant for a symbolic link. */
export const S_IFLNK = 0xa000;
/** File type constant for a regular file. */
export const S_IFREG = 0x8000;
/** File type constant for a block-oriented device file. */
export const S_IFBLK = 0x6000;
/** File type constant for a directory. */
export const S_IFDIR = 0x4000;
/** File type constant for a character-oriented device file. */
export const S_IFCHR = 0x2000;
/** File type constant for a FIFO/pipe. */
export const S_IFIFO = 0x1000;
/** Set user id */
export const S_ISUID = 0o4000;
/** Set group id */
export const S_ISGID = 0o2000;
/** Sticky bit */
export const S_ISVTX = 0o1000;
// File Mode Constants
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by owner. */
/** File mode indicating readable, writable and executable by owner. */
export const S_IRWXU = 0o700;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by owner. */
/** File mode indicating readable by owner. */
export const S_IRUSR = 0o400;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by owner. */
/** File mode indicating writable by owner. */
export const S_IWUSR = 0o200;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by owner. */
/** File mode indicating executable by owner. */
export const S_IXUSR = 0o100;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by group. */
/** File mode indicating readable, writable and executable by group. */
export const S_IRWXG = 0o70;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by group. */
/** File mode indicating readable by group. */
export const S_IRGRP = 0o40;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by group. */
/** File mode indicating writable by group. */
export const S_IWGRP = 0o20;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by group. */
/** File mode indicating executable by group. */
export const S_IXGRP = 0o10;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable, writable and executable by others. */
/** File mode indicating readable, writable and executable by others. */
export const S_IRWXO = 7;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating readable by others. */
/** File mode indicating readable by others. */
export const S_IROTH = 4;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating writable by others. */
/** File mode indicating writable by others. */
export const S_IWOTH = 2;
/** Constant for fs.Stats mode property for determining access permissions for a file. File mode indicating executable by others. */
/** File mode indicating executable by others. */
export const S_IXOTH = 1;
/// <reference types="node" resolution-mode="require"/>
import type { Dirent as _Dirent, Dir as _Dir } from 'fs';
import { NoArgCallback, TwoArgCallback } from '../filesystem.js';
import { Stats } from '../stats.js';
import type { NoArgCallback, TwoArgCallback } from '../filesystem.js';
import type { Stats } from '../stats.js';
export declare class Dirent implements _Dirent {

@@ -6,0 +6,0 @@ name: string;

@@ -8,3 +8,3 @@ /// <reference types="node" resolution-mode="require"/>

import { FileContents } from '../filesystem.js';
import { BigIntStats, Stats } from '../stats.js';
import { BigIntStats, type Stats } from '../stats.js';
import { Dirent } from './dir.js';

@@ -11,0 +11,0 @@ export declare class FileHandle implements BufferToUint8Array<Node.promises.FileHandle> {

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

const stats = await doOp('stat', true, path, cred);
return options?.bigint ? BigIntStats.clone(stats) : stats;
return options?.bigint ? new BigIntStats(stats) : stats;
}

@@ -220,3 +220,3 @@ stat;

const stats = await doOp('stat', false, path, cred);
return options?.bigint ? BigIntStats.clone(stats) : stats;
return options?.bigint ? new BigIntStats(stats) : stats;
}

@@ -253,3 +253,3 @@ lstat;

async function _open(_path, _flag, _mode = 0o644, resolveSymlinks) {
const path = normalizePath(_path), mode = normalizeMode(_mode, 0o644), flag = FileFlag.FromString(_flag);
const path = normalizePath(_path), mode = normalizeMode(_mode, 0o644), flag = FileFlag.Get(_flag);
try {

@@ -333,3 +333,3 @@ switch (flag.pathExistsAction()) {

const options = normalizeOptions(_options, null, 'r', null);
const flag = FileFlag.FromString(options.flag);
const flag = FileFlag.Get(options.flag);
if (!flag.isReadable()) {

@@ -370,3 +370,3 @@ throw new ApiError(ErrorCode.EINVAL, 'Flag passed must allow for reading.');

const options = normalizeOptions(_options, 'utf8', 'w', 0o644);
const flag = FileFlag.FromString(options.flag);
const flag = FileFlag.Get(options.flag);
if (!flag.isWriteable()) {

@@ -407,3 +407,3 @@ throw new ApiError(ErrorCode.EINVAL, 'Flag passed must allow for writing.');

const options = normalizeOptions(_options, 'utf8', 'a', 0o644);
const flag = FileFlag.FromString(options.flag);
const flag = FileFlag.Get(options.flag);
if (!flag.isAppendable()) {

@@ -410,0 +410,0 @@ throw new ApiError(ErrorCode.EINVAL, 'Flag passed to appendFile must allow for appending.');

/// <reference types="node" resolution-mode="require"/>
/// <reference types="node" resolution-mode="require"/>
import { FileContents } from '../filesystem.js';
import { BigIntStats, Stats } from '../stats.js';
import { BigIntStats, type Stats } from '../stats.js';
import type { symlink, ReadSyncOptions, BaseEncodingOptions, BufferEncodingOption } from 'fs';

@@ -6,0 +6,0 @@ import type * as Node from 'fs';

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

const stats = doOp('statSync', true, path, cred);
return options?.bigint ? BigIntStats.clone(stats) : stats;
return options?.bigint ? new BigIntStats(stats) : stats;
}

@@ -69,3 +69,3 @@ statSync;

const stats = doOp('statSync', false, path, cred);
return options?.bigint ? BigIntStats.clone(stats) : stats;
return options?.bigint ? new BigIntStats(stats) : stats;
}

@@ -97,3 +97,3 @@ lstatSync;

function _openSync(_path, _flag, _mode, resolveSymlinks) {
const path = normalizePath(_path), mode = normalizeMode(_mode, 0o644), flag = FileFlag.FromString(_flag);
const path = normalizePath(_path), mode = normalizeMode(_mode, 0o644), flag = FileFlag.Get(_flag);
// Check if the path exists, and is a file.

@@ -182,3 +182,3 @@ let stats;

const options = normalizeOptions(arg2, null, 'r', 0o644);
const flag = FileFlag.FromString(options.flag);
const flag = FileFlag.Get(options.flag);
if (!flag.isReadable()) {

@@ -208,3 +208,3 @@ throw new ApiError(ErrorCode.EINVAL, 'Flag passed to readFile must allow for reading.');

const options = normalizeOptions(_options, 'utf8', 'w', 0o644);
const flag = FileFlag.FromString(options.flag);
const flag = FileFlag.Get(options.flag);
if (!flag.isWriteable()) {

@@ -238,3 +238,3 @@ throw new ApiError(ErrorCode.EINVAL, 'Flag passed to writeFile must allow for writing.');

const options = normalizeOptions(arg3, 'utf8', 'a', 0o644);
const flag = FileFlag.FromString(options.flag);
const flag = FileFlag.Get(options.flag);
if (!flag.isAppendable()) {

@@ -252,3 +252,3 @@ throw new ApiError(ErrorCode.EINVAL, 'Flag passed to appendFile must allow for appending.');

const stats = fd2file(fd).statSync();
return options?.bigint ? BigIntStats.clone(stats) : stats;
return options?.bigint ? new BigIntStats(stats) : stats;
}

@@ -255,0 +255,0 @@ fstatSync;

@@ -20,2 +20,5 @@ import type { FileSystem } from './filesystem.js';

}
/**
* @hidden
*/
export declare enum ActionType {

@@ -46,5 +49,11 @@ NOP = 0,

export declare class FileFlag {
private static flagCache;
private static validFlagStrs;
/**
* Contains cached FileMode instances.
*/
protected static cache: Map<string | number, FileFlag>;
/**
* Array of valid mode strings.
*/
protected static validStrings: string[];
/**
* Get an object representing the given file flag.

@@ -55,17 +64,22 @@ * @param flag The string or number representing the flag

*/
static FromString(flag: string | number): FileFlag;
private flagStr;
static Get(flag: string | number): FileFlag;
protected _flag: string;
/**
* This should never be called directly.
* @param flag The string or number representing the flag
* @throw when the flag is invalid
*/
constructor(flag: string | number);
protected constructor(flag: string | number);
/**
* @param flag The number representing the flag
* @return The string representing the flag
* @throw when the flag number is invalid
* @returns The string representing the flag
* @throws when the flag number is invalid
*/
static NumberToString(flag: number): string;
static StringOf(flag: number): string;
/**
* @param flag The string representing the flag
* @returns The number representing the flag
* @throws when the flag string is invalid
*/
static NumberOf(flag: string): number;
/**
* Get the underlying flag string for this flag.

@@ -264,7 +278,7 @@ */

*/
export declare abstract class PreloadFile<T extends FileSystem> extends File {
export declare abstract class PreloadFile<FS extends FileSystem> extends File {
/**
* The file system that created the file.
*/
protected fs: T;
protected fs: FS;
/**

@@ -295,3 +309,3 @@ * Path to the file

*/
fs: T,
fs: FS,
/**

@@ -298,0 +312,0 @@ * Path to the file

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

import { Stats } from './stats.js';
/**
* @hidden
*/
export var ActionType;

@@ -42,11 +45,10 @@ (function (ActionType) {

*/
static FromString(flag) {
static Get(flag) {
// Check cache first.
if (!FileFlag.flagCache.has(flag)) {
FileFlag.flagCache.set(flag, new FileFlag(flag));
if (!FileFlag.cache.has(flag)) {
FileFlag.cache.set(flag, new FileFlag(flag));
}
return FileFlag.flagCache.get(flag);
return FileFlag.cache.get(flag);
}
/**
* This should never be called directly.
* @param flag The string or number representing the flag

@@ -56,16 +58,16 @@ * @throw when the flag is invalid

constructor(flag) {
if (typeof flag === 'number') {
flag = FileFlag.NumberToString(flag);
if (typeof flag == 'number') {
flag = FileFlag.StringOf(flag);
}
if (FileFlag.validFlagStrs.indexOf(flag) < 0) {
if (!FileFlag.validStrings.includes(flag)) {
throw new ApiError(ErrorCode.EINVAL, 'Invalid flag string: ' + flag);
}
this.flagStr = flag;
this._flag = flag;
}
/**
* @param flag The number representing the flag
* @return The string representing the flag
* @throw when the flag number is invalid
* @returns The string representing the flag
* @throws when the flag number is invalid
*/
static NumberToString(flag) {
static StringOf(flag) {
// based on https://github.com/nodejs/node/blob/abbdc3efaa455e6c907ebef5409ac8b0f222f969/lib/internal/fs/utils.js#L619

@@ -102,6 +104,41 @@ switch (flag) {

/**
* @param flag The string representing the flag
* @returns The number representing the flag
* @throws when the flag string is invalid
*/
static NumberOf(flag) {
switch (flag) {
case 'r':
return O_RDONLY;
case 'rs':
return O_RDONLY | O_SYNC;
case 'r+':
return O_RDWR;
case 'rs+':
return O_RDWR | O_SYNC;
case 'w':
return O_TRUNC | O_CREAT | O_WRONLY;
case 'wx':
return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL;
case 'w+':
return O_TRUNC | O_CREAT | O_RDWR;
case 'wx+':
return O_TRUNC | O_CREAT | O_RDWR | O_EXCL;
case 'a':
return O_APPEND | O_CREAT | O_WRONLY;
case 'ax':
return O_APPEND | O_CREAT | O_WRONLY | O_EXCL;
case 'a+':
return O_APPEND | O_CREAT | O_RDWR;
case 'ax+':
return O_APPEND | O_CREAT | O_RDWR | O_EXCL;
default:
throw new ApiError(ErrorCode.EINVAL, 'Invalid flag string: ' + flag);
}
}
/**
* Get the underlying flag string for this flag.
*/
toString() {
return this.flagStr;
return this._flag;
}

@@ -125,3 +162,3 @@ /**

isReadable() {
return this.flagStr.indexOf('r') !== -1 || this.flagStr.indexOf('+') !== -1;
return this._flag.indexOf('r') != -1 || this._flag.indexOf('+') != -1;
}

@@ -132,3 +169,3 @@ /**

isWriteable() {
return this.flagStr.indexOf('w') !== -1 || this.flagStr.indexOf('a') !== -1 || this.flagStr.indexOf('+') !== -1;
return this._flag.indexOf('w') != -1 || this._flag.indexOf('a') != -1 || this._flag.indexOf('+') != -1;
}

@@ -139,3 +176,3 @@ /**

isTruncating() {
return this.flagStr.indexOf('w') !== -1;
return this._flag.indexOf('w') !== -1;
}

@@ -146,3 +183,3 @@ /**

isAppendable() {
return this.flagStr.indexOf('a') !== -1;
return this._flag.indexOf('a') !== -1;
}

@@ -153,3 +190,3 @@ /**

isSynchronous() {
return this.flagStr.indexOf('s') !== -1;
return this._flag.indexOf('s') !== -1;
}

@@ -160,3 +197,3 @@ /**

isExclusive() {
return this.flagStr.indexOf('x') !== -1;
return this._flag.indexOf('x') !== -1;
}

@@ -181,14 +218,16 @@ /**

pathNotExistsAction() {
if ((this.isWriteable() || this.isAppendable()) && this.flagStr !== 'r+') {
if ((this.isWriteable() || this.isAppendable()) && this._flag != 'r+') {
return ActionType.CREATE;
}
else {
return ActionType.THROW;
}
return ActionType.THROW;
}
}
// Contains cached FileMode instances.
FileFlag.flagCache = new Map();
// Array of valid mode strings.
FileFlag.validFlagStrs = ['r', 'r+', 'rs', 'rs+', 'w', 'wx', 'w+', 'wx+', 'a', 'ax', 'a+', 'ax+'];
/**
* Contains cached FileMode instances.
*/
FileFlag.cache = new Map();
/**
* Array of valid mode strings.
*/
FileFlag.validStrings = ['r', 'r+', 'rs', 'rs+', 'w', 'wx', 'w+', 'wx+', 'a', 'ax', 'a+', 'ax+'];
export class File {

@@ -296,3 +335,3 @@ /**

async stat() {
return Stats.clone(this.stats);
return new Stats(this.stats);
}

@@ -303,3 +342,3 @@ /**

statSync() {
return Stats.clone(this.stats);
return new Stats(this.stats);
}

@@ -306,0 +345,0 @@ /**

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

declare const AsyncFileIndexFS_base: (abstract new (...args: any[]) => {
/**
* Returns the inode for the indicated item, or null if it does not exist.
* @param path Name of item in this directory.
*/
metadata(): import("./filesystem.js").FileSystemMetadata;

@@ -221,0 +225,0 @@ renameSync(oldPath: string, newPath: string, cred: Cred): void;

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

// This inode doesn't have correct size information, noted with -1.
inode = new IndexFileInode(new Stats(FileType.FILE, -1, 0o555));
inode = new IndexFileInode(new Stats({ mode: FileType.FILE | 0o555 }));
}

@@ -223,3 +223,3 @@ if (!parent) {

toStats() {
return new Stats(FileType.FILE, 4096, 0o666);
return new Stats({ mode: FileType.FILE | 0o666, size: 4096 });
}

@@ -249,3 +249,3 @@ }

get stats() {
return new Stats(FileType.DIRECTORY, 4096, 0o555);
return new Stats({ mode: FileType.DIRECTORY | 0o555, size: 4096 });
}

@@ -252,0 +252,0 @@ /**

import { ApiError } from './ApiError.js';
import { Stats } from './stats.js';
import { File, FileFlag } from './file.js';
import { Cred } from './cred.js';
import type { Stats } from './stats.js';
import type { File, FileFlag } from './file.js';
import type { Cred } from './cred.js';
export type NoArgCallback = (e?: ApiError) => unknown;

@@ -6,0 +6,0 @@ export type TwoArgCallback<T> = (e?: ApiError, rv?: T) => unknown;

@@ -6,3 +6,2 @@ /**

import { FileSystem } from './filesystem.js';
import { backends } from './backends/index.js';
import { type Backend, type BackendConfig } from './backends/backend.js';

@@ -19,3 +18,3 @@ /**

export interface ConfigMapping {
[mountPoint: string]: FileSystem | BackendConfig | keyof typeof backends | Backend;
[mountPoint: string]: FileSystem | BackendConfig | Backend;
}

@@ -31,4 +30,8 @@ /**

export declare function configure(config: Configuration): Promise<void>;
export * from './backends/index.js';
export type { Backend, BackendConfig } from './backends/backend.js';
export * from './backends/AsyncMirror.js';
export * from './backends/AsyncStore.js';
export * from './backends/InMemory.js';
export * from './backends/Locked.js';
export * from './backends/Overlay.js';
export * from './backends/SyncStore.js';

@@ -35,0 +38,0 @@ export * from './ApiError.js';

@@ -6,3 +6,2 @@ /**

import { FileSystem } from './filesystem.js';
import { backends } from './backends/index.js';
import { Cred } from './cred.js';

@@ -35,5 +34,2 @@ import { isBackend, resolveBackendConfig } from './backends/backend.js';

}
if (typeof value == 'string') {
value = { backend: backends[value] };
}
if (isBackend(value)) {

@@ -46,4 +42,7 @@ value = { backend: value };

}
export * from './backends/index.js';
export * from './backends/AsyncMirror.js';
export * from './backends/AsyncStore.js';
export * from './backends/InMemory.js';
export * from './backends/Locked.js';
export * from './backends/Overlay.js';
export * from './backends/SyncStore.js';

@@ -50,0 +49,0 @@ export * from './ApiError.js';

@@ -1,11 +0,19 @@

import { Stats } from './stats.js';
import { Stats, type StatsLike } from './stats.js';
/**
* Alias for an ino.
* This will be helpful if in the future inode numbers/IDs are changed to strings or numbers.
*/
export type Ino = bigint;
/**
* Max 32-bit integer
* @hidden
*/
export declare const size_max: number;
/**
* @internal
* Room inode
* @hidden
*/
export declare const rootIno: Ino;
/**
* Generate 4 random bits at a time
*
* Generate a random ino
* @internal

@@ -17,3 +25,3 @@ */

*/
export declare class Inode {
export declare class Inode implements StatsLike {
readonly buffer: ArrayBufferLike;

@@ -35,8 +43,10 @@ get data(): Uint8Array;

set gid(value: number);
get atime(): number;
set atime(value: number);
get mtime(): number;
set mtime(value: number);
get ctime(): number;
set ctime(value: number);
get atimeMs(): number;
set atimeMs(value: number);
get birthtimeMs(): number;
set birthtimeMs(value: number);
get mtimeMs(): number;
set mtimeMs(value: number);
get ctimeMs(): number;
set ctimeMs(value: number);
/**

@@ -47,6 +57,2 @@ * Handy function that converts the Inode to a Node Stats object.

/**
* Get the size of this Inode, in bytes.
*/
sizeof(): number;
/**
* Updates the Inode using information from the stats object. Used by file

@@ -53,0 +59,0 @@ * systems at sync time, e.g.:

@@ -1,18 +0,10 @@

import { S_IFMT } from './emulation/constants.js';
import { Stats, FileType } from './stats.js';
var Offset;
(function (Offset) {
Offset[Offset["ino"] = 0] = "ino";
Offset[Offset["size"] = 8] = "size";
Offset[Offset["mode"] = 12] = "mode";
Offset[Offset["nlink"] = 14] = "nlink";
Offset[Offset["uid"] = 18] = "uid";
Offset[Offset["gid"] = 22] = "gid";
Offset[Offset["atime"] = 26] = "atime";
Offset[Offset["mtime"] = 34] = "mtime";
Offset[Offset["ctime"] = 42] = "ctime";
})(Offset || (Offset = {}));
import { Stats } from './stats.js';
/**
* Max 32-bit integer
* @hidden
*/
export const size_max = 2 ** 32 - 1;
/**
* @internal
* Room inode
* @hidden
*/

@@ -27,4 +19,3 @@ export const rootIno = 0n;

/**
* Generate 4 random bits at a time
*
* Generate a random ino
* @internal

@@ -36,2 +27,19 @@ */

/**
* Offsets for inode members
*/
var Offset;
(function (Offset) {
Offset[Offset["ino"] = 0] = "ino";
Offset[Offset["size"] = 8] = "size";
Offset[Offset["mode"] = 12] = "mode";
Offset[Offset["nlink"] = 14] = "nlink";
Offset[Offset["uid"] = 18] = "uid";
Offset[Offset["gid"] = 22] = "gid";
Offset[Offset["atime"] = 26] = "atime";
Offset[Offset["birthtime"] = 34] = "birthtime";
Offset[Offset["mtime"] = 42] = "mtime";
Offset[Offset["ctime"] = 50] = "ctime";
Offset[Offset["end"] = 58] = "end";
})(Offset || (Offset = {}));
/**
* Generic inode definition that can easily be serialized.

@@ -45,3 +53,6 @@ */

const setDefaults = !buffer;
buffer ?? (buffer = new ArrayBuffer(50));
buffer ?? (buffer = new ArrayBuffer(Offset.end));
if (buffer?.byteLength < Offset.end) {
throw new RangeError(`Can not create an inode from a buffer less than ${Offset.end} bytes`);
}
this.view = new DataView(buffer);

@@ -57,5 +68,6 @@ this.buffer = buffer;

const now = Date.now();
this.atime = now;
this.mtime = now;
this.ctime = now;
this.atimeMs = now;
this.mtimeMs = now;
this.ctimeMs = now;
this.birthtimeMs = now;
}

@@ -98,18 +110,24 @@ get ino() {

}
get atime() {
get atimeMs() {
return this.view.getFloat64(Offset.atime, true);
}
set atime(value) {
set atimeMs(value) {
this.view.setFloat64(Offset.atime, value, true);
}
get mtime() {
get birthtimeMs() {
return this.view.getFloat64(Offset.birthtime, true);
}
set birthtimeMs(value) {
this.view.setFloat64(Offset.birthtime, value, true);
}
get mtimeMs() {
return this.view.getFloat64(Offset.mtime, true);
}
set mtime(value) {
set mtimeMs(value) {
this.view.setFloat64(Offset.mtime, value, true);
}
get ctime() {
get ctimeMs() {
return this.view.getFloat64(Offset.ctime, true);
}
set ctime(value) {
set ctimeMs(value) {
this.view.setFloat64(Offset.ctime, value, true);

@@ -121,11 +139,5 @@ }

toStats() {
return new Stats((this.mode & S_IFMT) === FileType.DIRECTORY ? FileType.DIRECTORY : FileType.FILE, this.size, this.mode, this.atime, this.mtime, this.ctime, this.uid, this.gid);
return new Stats(this);
}
/**
* Get the size of this Inode, in bytes.
*/
sizeof() {
return this.buffer.byteLength;
}
/**
* Updates the Inode using information from the stats object. Used by file

@@ -162,12 +174,12 @@ * systems at sync time, e.g.:

}
if (this.atime !== stats.atimeMs) {
this.atime = stats.atimeMs;
if (this.atimeMs !== stats.atimeMs) {
this.atimeMs = stats.atimeMs;
hasChanged = true;
}
if (this.mtime !== stats.mtimeMs) {
this.mtime = stats.mtimeMs;
if (this.mtimeMs !== stats.mtimeMs) {
this.mtimeMs = stats.mtimeMs;
hasChanged = true;
}
if (this.ctime !== stats.ctimeMs) {
this.ctime = stats.ctimeMs;
if (this.ctimeMs !== stats.ctimeMs) {
this.ctimeMs = stats.ctimeMs;
hasChanged = true;

@@ -174,0 +186,0 @@ }

@@ -1,2 +0,1 @@

export type MutexCallback = () => void;
/**

@@ -6,3 +5,3 @@ * Non-recursive mutex

*/
export default class Mutex {
export declare class Mutex {
private _locks;

@@ -9,0 +8,0 @@ lock(path: string): Promise<void>;

@@ -5,3 +5,3 @@ /**

*/
export default class Mutex {
export class Mutex {
constructor() {

@@ -8,0 +8,0 @@ this._locks = new Map();

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

/**
* Common code used by both Stats and BigIntStats
*
*/
export declare abstract class StatsCommon<T extends number | bigint> implements Node.StatsBase<T> {
export interface StatsLike {
/**
* Size of the item in bytes.
* For directories/symlinks, this is normally the size of the struct that represents the item.
*/
size: number | bigint;
/**
* Unix-style file mode (e.g. 0o644) that includes the item type
* Type of the item can be FILE, DIRECTORY, SYMLINK, or SOCKET
*/
mode: number | bigint;
/**
* time of last access, in milliseconds since epoch
*/
atimeMs: number | bigint;
/**
* time of last modification, in milliseconds since epoch
*/
mtimeMs: number | bigint;
/**
* time of last time file status was changed, in milliseconds since epoch
*/
ctimeMs: number | bigint;
/**
* time of file creation, in milliseconds since epoch
*/
birthtimeMs: number | bigint;
/**
* the id of the user that owns the file
*/
uid: number | bigint;
/**
* the id of the group that owns the file
*/
gid: number | bigint;
}
/**
* Provides information about a particular entry in the file system.
* Common code used by both Stats and BigIntStats.
*/
export declare abstract class StatsCommon<T extends number | bigint> implements Node.StatsBase<T>, StatsLike {
protected abstract _isBigint: boolean;

@@ -22,2 +62,6 @@ protected get _typename(): string;

blocks: T;
/**
* Unix-style file mode (e.g. 0o644) that includes the type of the item.
* Type of the item can be FILE, DIRECTORY, SYMLINK, or SOCKET
*/
mode: T;

@@ -56,29 +100,35 @@ /**

fileData?: Uint8Array;
/**
* time of last access, in milliseconds since epoch
*/
atimeMs: T;
get atime(): Date;
set atime(value: Date);
/**
* time of last modification, in milliseconds since epoch
*/
mtimeMs: T;
get mtime(): Date;
set mtime(value: Date);
/**
* time of last time file status was changed, in milliseconds since epoch
*/
ctimeMs: T;
get ctime(): Date;
set ctime(value: Date);
/**
* time of file creation, in milliseconds since epoch
*/
birthtimeMs: T;
get birthtime(): Date;
set birthtime(value: Date);
/**
* Size of the item in bytes.
* For directories/symlinks, this is normally the size of the struct that represents the item.
*/
size: T;
/**
* Provides information about a particular entry in the file system.
* @param itemType Type of the item (FILE, DIRECTORY, SYMLINK, or SOCKET)
* @param size Size of the item in bytes. For directories/symlinks,
* this is normally the size of the struct that represents the item.
* @param mode Unix-style file mode (e.g. 0o644)
* @param atimeMs time of last access, in milliseconds since epoch
* @param mtimeMs time of last modification, in milliseconds since epoch
* @param ctimeMs time of last time file status was changed, in milliseconds since epoch
* @param uid the id of the user that owns the file
* @param gid the id of the group that owns the file
* @param birthtimeMs time of file creation, in milliseconds since epoch
* Creates a new stats instance from a stats-like object. Can be used to copy stats (note)
*/
constructor(itemType?: FileType, size?: number | bigint, mode?: number | bigint, atimeMs?: number | bigint, mtimeMs?: number | bigint, ctimeMs?: number | bigint, uid?: number | bigint, gid?: number | bigint, birthtimeMs?: number | bigint);
constructor({ atimeMs, mtimeMs, ctimeMs, birthtimeMs, uid, gid, size, mode }?: Partial<StatsLike>);
/**

@@ -134,8 +184,9 @@ * @returns true if this item is a file.

*/
export declare class Stats extends StatsCommon<number> implements Node.Stats {
export declare class Stats extends StatsCommon<number> implements Node.Stats, StatsLike {
protected _isBigint: boolean;
/**
* Clones the stats object.
* @deprecated use `new Stats(stats)`
*/
static clone(s: Stats): Stats;
static clone(stats: Stats): Stats;
}

@@ -146,3 +197,3 @@ /**

*/
export declare class BigIntStats extends StatsCommon<bigint> implements Node.BigIntStats {
export declare class BigIntStats extends StatsCommon<bigint> implements Node.BigIntStats, StatsLike {
protected _isBigint: boolean;

@@ -155,4 +206,5 @@ atimeNs: bigint;

* Clone a stats object.
* @deprecated use `new BigIntStats(stats)`
*/
static clone(s: BigIntStats | Stats): BigIntStats;
static clone(stats: BigIntStats | Stats): BigIntStats;
}

@@ -13,3 +13,4 @@ import { Cred } from './cred.js';

/**
* Common code used by both Stats and BigIntStats
* Provides information about a particular entry in the file system.
* Common code used by both Stats and BigIntStats.
*/

@@ -51,15 +52,5 @@ export class StatsCommon {

/**
* Provides information about a particular entry in the file system.
* @param itemType Type of the item (FILE, DIRECTORY, SYMLINK, or SOCKET)
* @param size Size of the item in bytes. For directories/symlinks,
* this is normally the size of the struct that represents the item.
* @param mode Unix-style file mode (e.g. 0o644)
* @param atimeMs time of last access, in milliseconds since epoch
* @param mtimeMs time of last modification, in milliseconds since epoch
* @param ctimeMs time of last time file status was changed, in milliseconds since epoch
* @param uid the id of the user that owns the file
* @param gid the id of the group that owns the file
* @param birthtimeMs time of file creation, in milliseconds since epoch
* Creates a new stats instance from a stats-like object. Can be used to copy stats (note)
*/
constructor(itemType = FileType.FILE, size = -1, mode, atimeMs, mtimeMs, ctimeMs, uid, gid, birthtimeMs) {
constructor({ atimeMs, mtimeMs, ctimeMs, birthtimeMs, uid, gid, size, mode } = {}) {
/**

@@ -98,3 +89,3 @@ * ID of device containing file

const currentTime = Date.now();
const resolveT = (v, def) => (typeof v == this._typename ? v : this._convert(typeof v == this._typename_inverse ? v : def));
const resolveT = (val, _default) => (typeof val == this._typename ? val : this._convert(typeof val == this._typename_inverse ? val : _default));
this.atimeMs = resolveT(atimeMs, currentTime);

@@ -107,2 +98,3 @@ this.mtimeMs = resolveT(mtimeMs, currentTime);

this.size = this._convert(size);
const itemType = Number(mode) & S_IFMT || FileType.FILE;
if (mode) {

@@ -236,5 +228,6 @@ this.mode = this._convert(mode);

* Clones the stats object.
* @deprecated use `new Stats(stats)`
*/
static clone(s) {
return new Stats(s.mode & S_IFMT, s.size, s.mode & ~S_IFMT, s.atimeMs, s.mtimeMs, s.ctimeMs, s.uid, s.gid, s.birthtimeMs);
static clone(stats) {
return new Stats(stats);
}

@@ -254,7 +247,8 @@ }

* Clone a stats object.
* @deprecated use `new BigIntStats(stats)`
*/
static clone(s) {
return new BigIntStats(Number(s.mode) & S_IFMT, BigInt(s.size), BigInt(s.mode) & BigInt(~S_IFMT), BigInt(s.atimeMs), BigInt(s.mtimeMs), BigInt(s.ctimeMs), BigInt(s.uid), BigInt(s.gid), BigInt(s.birthtimeMs));
static clone(stats) {
return new BigIntStats(stats);
}
}
BigIntStats;

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

* Synchronous recursive makedir.
* @internal
* @hidden
*/

@@ -16,3 +16,3 @@ export declare function mkdirpSync(p: string, mode: number, cred: Cred, fs: FileSystem): void;

* Calculates levenshtein distance.
* @internal
* @hidden
*/

@@ -23,9 +23,4 @@ export declare function levenshtein(a: string, b: string): number;

/**
* Converts a callback into a promise. Assumes last parameter is the callback
* @todo Look at changing resolve value from cbArgs[0] to include other callback arguments?
* @hidden
*/
export declare function toPromise(fn: (...fnArgs: unknown[]) => unknown): (...args: unknown[]) => Promise<unknown>;
/**
* @internal
*/
export declare const setImmediate: (callback: () => unknown) => void;

@@ -32,0 +27,0 @@ /**

import { ApiError, ErrorCode } from './ApiError.js';
import * as path from './emulation/path.js';
import { dirname } from './emulation/path.js';
/**
* Synchronous recursive makedir.
* @internal
* @hidden
*/
export function mkdirpSync(p, mode, cred, fs) {
if (!fs.existsSync(p, cred)) {
mkdirpSync(path.dirname(p), mode, cred, fs);
mkdirpSync(dirname(p), mode, cred, fs);
fs.mkdirSync(p, mode, cred);
}
}
/*
* Levenshtein distance, from the `js-levenshtein` NPM module.
* Copied here to avoid complexity of adding another CommonJS module dependency.
*/
function _min(d0, d1, d2, bx, ay) {

@@ -22,3 +18,3 @@ return Math.min(d0 + 1, d1 + 1, d2 + 1, bx === ay ? d1 : d1 + 1);

* Calculates levenshtein distance.
* @internal
* @hidden
*/

@@ -98,23 +94,4 @@ export function levenshtein(a, b) {

/**
* Converts a callback into a promise. Assumes last parameter is the callback
* @todo Look at changing resolve value from cbArgs[0] to include other callback arguments?
* @hidden
*/
export function toPromise(fn) {
return function (...args) {
return new Promise((resolve, reject) => {
args.push((e, ...cbArgs) => {
if (e) {
reject(e);
}
else {
resolve(cbArgs[0]);
}
});
fn(...args);
});
};
}
/**
* @internal
*/
export const setImmediate = typeof globalThis.setImmediate == 'function' ? globalThis.setImmediate : cb => setTimeout(cb, 0);

@@ -126,17 +103,41 @@ /**

export function encode(input, encoding = 'utf8') {
if (typeof input != 'string') {
throw new ApiError(ErrorCode.EINVAL, 'Can not encode a non-string');
}
switch (encoding) {
case 'ascii':
return new globalThis.TextEncoder().encode(input).map(v => v & 0x7f);
case 'latin1':
case 'binary':
return new Uint8Array(Array.from(input).map(char => char.charCodeAt(0)));
case 'utf8':
case 'utf-8':
return new Uint8Array(Array.from(input).flatMap(char => {
const code = char.charCodeAt(0);
if (code < 0x80) {
return code;
}
const a = (code & 0x3f) | 0x80;
if (code < 0x800) {
return [(code >> 6) | 0xc0, a];
}
const b = ((code >> 6) & 0x3f) | 0x80;
if (code < 0x10000) {
return [(code >> 12) | 0xe0, b, a];
}
return [(code >> 18) | 0xf0, ((code >> 12) & 0x3f) | 0x80, b, a];
}));
case 'base64':
return encode(atob(input), 'utf-8');
case 'base64url':
return encode(input.replace('_', '/').replace('-', '+'), 'base64');
case 'hex':
return new globalThis.TextEncoder().encode(input);
return new Uint8Array(input.match(/.{1,2}/g).map(e => parseInt(e, 16)));
case 'utf16le':
case 'ucs2':
case 'ucs-2':
return new globalThis.TextEncoder().encode(input).slice(0, -1);
const u16 = new Uint16Array(new ArrayBuffer(input.length * 2));
for (let i = 0; i < input.length; i++) {
u16[i] = input.charCodeAt(i);
}
return new Uint8Array(u16.buffer);
default:

@@ -151,10 +152,32 @@ throw new ApiError(ErrorCode.EINVAL, 'Invalid encoding: ' + encoding);

export function decode(input, encoding = 'utf8') {
if (!(input instanceof Uint8Array)) {
throw new ApiError(ErrorCode.EINVAL, 'Can not decode a non-Uint8Array');
}
switch (encoding) {
case 'ascii':
case 'latin1':
case 'binary':
return Array.from(input)
.map(char => String.fromCharCode(char))
.join('');
case 'utf8':
case 'utf-8':
return new globalThis.TextDecoder().decode(input);
case 'latin1':
case 'binary':
return new globalThis.TextDecoder('latin1').decode(input);
let utf8String = '';
for (let i = 0; i < input.length; i++) {
let code;
if (input[i] < 0x80) {
code = input[i];
}
else if (input[i] < 0xe0) {
code = ((input[i] & 0x1f) << 6) | (input[++i] & 0x3f);
}
else if (input[i] < 0xf0) {
code = ((input[i] & 0x0f) << 12) | ((input[++i] & 0x3f) << 6) | (input[++i] & 0x3f);
}
else {
code = ((input[i] & 0x07) << 18) | ((input[++i] & 0x3f) << 12) | ((input[++i] & 0x3f) << 6) | (input[++i] & 0x3f);
}
utf8String += String.fromCharCode(code);
}
return utf8String;
case 'utf16le':

@@ -170,5 +193,3 @@ case 'ucs2':

case 'base64':
return btoa(Array.from(input)
.map(v => String.fromCharCode(v))
.join(''));
return btoa(decode(input, 'utf-8'));
case 'base64url':

@@ -178,3 +199,3 @@ return decode(input, 'base64').replace('/', '_').replace('+', '-');

return Array.from(input)
.map(e => e.toString(16))
.map(e => e.toString(16).padStart(2, '0'))
.join('');

@@ -181,0 +202,0 @@ default:

{
"name": "@zenfs/core",
"version": "0.3.5",
"version": "0.4.0",
"description": "A filesystem in your browser",

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

],
"bin": {
"make-index": "./scripts/make-index.js"
},
"type": "module",

@@ -50,2 +53,3 @@ "homepage": "https://github.com/zen-fs/core",

"@types/readable-stream": "^4.0.10",
"minimatch": "^9.0.3",
"readable-stream": "^4.5.2"

@@ -52,0 +56,0 @@ },

@@ -42,3 +42,3 @@ # ZenFS

#### Using different and/or different backends
#### Using different and/or multiple backends

@@ -54,3 +54,3 @@ A single `InMemory` backend is created by default, mounted on `/`.

```js
import { configure } from '@zenfs/core';
import { configure, InMemory } from '@zenfs/core';
import { IndexedDB } from '@zenfs/dom';

@@ -63,3 +63,3 @@ import { Zip } from '@zenfs/zip';

'/mnt/zip': { backend: Zip, zipData },
'/tmp': 'InMemory',
'/tmp': InMemory,
'/home': IndexedDB,

@@ -70,3 +70,7 @@ };

> [!TIP]
> When configuring a mount point, you can pass in 1. A string that maps to a built-in backend 2. A `Backend` object, if the backend has no required options 3. An object that has a `backend` property which is a `Backend` or a string that maps to a built-in backend and the options accepted by the backend
> When configuring a mount point, you can pass in
>
> 1. A string that maps to a built-in backend
> 2. A `Backend` object, if the backend has no required options
> 3. An object that has the options accepted by the backend and a `backend` property which is (1) or (2)

@@ -116,3 +120,3 @@ Here is an example that mounts the `Storage` backend from `@zenfs/dom` on `/`:

```js
import { configure, fs } from '@zenfs/core';
import { configure, fs, AsyncMirror, InMemory } from '@zenfs/core';
import { IndexedDB } from '@zenfs/dom';

@@ -122,4 +126,4 @@

'/': {
backend: 'AsyncMirror',
sync: 'InMemory',
backend: AsyncMirror,
sync: InMemory,
async: IndexedDB,

@@ -139,3 +143,3 @@ },

```js
import { configure, createBackend } from '@zenfs/core';
import { configure, createBackend, InMemory } from '@zenfs/core';
import { IndexedDB } from '@zenfs/dom';

@@ -145,3 +149,3 @@ import { Zip } from '@zenfs/zip';

await configure({
'/tmp': 'InMemory',
'/tmp': InMemory,
'/home': IndexedDB,

@@ -148,0 +152,0 @@ };

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