Socket
Socket
Sign inDemoInstall

memfs

Package Overview
Dependencies
11
Maintainers
1
Versions
145
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.0.0 to 4.1.0-next.1

lib/__tests__/util.d.ts

3

lib/Dirent.d.ts
import { Link } from './node';
import { TEncodingExtended, TDataOut } from './encoding';
import type { IDirent } from './node/types/misc';
/**
* A directory entry, like `fs.Dirent`.
*/
export declare class Dirent {
export declare class Dirent implements IDirent {
static build(link: Link, encoding: TEncodingExtended | undefined): Dirent;

@@ -8,0 +9,0 @@ name: TDataOut;

@@ -9,9 +9,9 @@ export interface IPermissionStatus {

isSameEntry(fileSystemHandle: IFileSystemHandle): boolean;
queryPermission(fileSystemHandlePermissionDescriptor: NodeFileSystemHandlePermissionDescriptor): IPermissionStatus;
queryPermission(fileSystemHandlePermissionDescriptor: FileSystemHandlePermissionDescriptor): IPermissionStatus;
remove(options?: {
recursive?: boolean;
}): Promise<void>;
requestPermission(fileSystemHandlePermissionDescriptor: NodeFileSystemHandlePermissionDescriptor): IPermissionStatus;
requestPermission(fileSystemHandlePermissionDescriptor: FileSystemHandlePermissionDescriptor): IPermissionStatus;
}
export interface NodeFileSystemHandlePermissionDescriptor {
export interface FileSystemHandlePermissionDescriptor {
mode: 'read' | 'readwrite';

@@ -18,0 +18,0 @@ }

import Stats from './Stats';
import Dirent from './Dirent';
import { Volume as _Volume, StatWatcher, FSWatcher, IReadStream, IWriteStream, DirectoryJSON } from './volume';
import { Volume as _Volume, StatWatcher, FSWatcher, IWriteStream, DirectoryJSON, NestedDirectoryJSON } from './volume';
import { constants } from './constants';
import type { FsPromisesApi } from './node/types';
export { DirectoryJSON };
import type * as misc from './node/types/misc';
export { DirectoryJSON, NestedDirectoryJSON };
export declare const Volume: typeof _Volume;

@@ -15,3 +16,3 @@ export declare const vol: _Volume;

FSWatcher: new () => FSWatcher;
ReadStream: new (...args: any[]) => IReadStream;
ReadStream: new (...args: any[]) => misc.IReadStream;
WriteStream: new (...args: any[]) => IWriteStream;

@@ -33,5 +34,5 @@ promises: FsPromisesApi;

*/
export declare const memfs: (json?: DirectoryJSON, cwd?: string) => IFs;
export declare const memfs: (json?: NestedDirectoryJSON, cwd?: string) => IFs;
export type IFsWithVolume = IFs & {
__vol: _Volume;
};

@@ -44,3 +44,3 @@ "use strict";

const memfs = (json = {}, cwd = '/') => {
const volume = exports.Volume.fromJSON(json, cwd);
const volume = exports.Volume.fromNestedJSON(json, cwd);
const fs = createFsFromVolume(volume);

@@ -47,0 +47,0 @@ return fs;

@@ -152,3 +152,3 @@ /// <reference types="node" />

stats(): Stats<number>;
write(buf: Buffer, offset?: number, length?: number, position?: number): number;
write(buf: Buffer, offset?: number, length?: number, position?: number | null): number;
read(buf: Buffer | ArrayBufferView | DataView, offset?: number, length?: number, position?: number): number;

@@ -155,0 +155,0 @@ chmod(perm: number): void;

import type { FsCallbackApi, FsPromisesApi } from './types';
export declare function createPromisesApi(vol: FsCallbackApi): null | FsPromisesApi;
export declare function createPromisesApi(vol: FsCallbackApi): FsPromisesApi;

@@ -7,4 +7,2 @@ "use strict";

function createPromisesApi(vol) {
if (typeof Promise === 'undefined')
return null;
return {

@@ -45,3 +43,3 @@ FileHandle: FileHandle_1.FileHandle,

},
open(path, flags, mode) {
open(path, flags = 'r', mode) {
return (0, util_1.promisify)(vol, 'open', fd => new FileHandle_1.FileHandle(vol, fd))(path, flags, mode);

@@ -48,0 +46,0 @@ },

/// <reference types="node" />
/// <reference types="node" />
import type { PathLike, symlink } from 'fs';
import type * as misc from './misc';
import type * as opts from './options';
export interface FsCallbackApi {
open(path: PathLike, flags: misc.TFlags, /* ... */ callback: misc.TCallback<number>): any;
open(path: PathLike, flags: misc.TFlags, mode: misc.TMode, callback: misc.TCallback<number>): any;
open(path: misc.PathLike, flags: misc.TFlags, callback: misc.TCallback<number>): any;
open(path: misc.PathLike, flags: misc.TFlags, mode: misc.TMode, callback: misc.TCallback<number>): any;
close(fd: number, callback: misc.TCallback<void>): void;

@@ -13,36 +12,26 @@ read(fd: number, buffer: Buffer | ArrayBufferView | DataView, offset: number, length: number, position: number, callback: (err?: Error | null, bytesRead?: number, buffer?: Buffer | ArrayBufferView | DataView) => void): void;

readFile(id: misc.TFileId, options: opts.IReadFileOptions | string, callback: misc.TCallback<misc.TDataOut>): any;
write(fd: number, buffer: Buffer | ArrayBufferView | DataView, callback: (...args: any[]) => void): any;
write(fd: number, buffer: Buffer | ArrayBufferView | DataView, offset: number, callback: (...args: any[]) => void): any;
write(fd: number, buffer: Buffer | ArrayBufferView | DataView, offset: number, length: number, callback: (...args: any[]) => void): any;
write(fd: number, buffer: Buffer | ArrayBufferView | DataView, offset: number, length: number, position: number, callback: (...args: any[]) => void): any;
write(fd: number, str: string, callback: (...args: any[]) => void): any;
write(fd: number, str: string, position: number, callback: (...args: any[]) => void): any;
write(fd: number, str: string, position: number, encoding: BufferEncoding, callback: (...args: any[]) => void): any;
writeFile(id: misc.TFileId, data: misc.TData, callback: misc.TCallback<void>): any;
writeFile(id: misc.TFileId, data: misc.TData, options: opts.IWriteFileOptions | string, callback: misc.TCallback<void>): any;
copyFile(src: PathLike, dest: PathLike, callback: misc.TCallback<void>): any;
copyFile(src: PathLike, dest: PathLike, flags: misc.TFlagsCopy, callback: misc.TCallback<void>): any;
link(existingPath: PathLike, newPath: PathLike, callback: misc.TCallback<void>): void;
unlink(path: PathLike, callback: misc.TCallback<void>): void;
symlink(target: PathLike, path: PathLike, callback: misc.TCallback<void>): any;
symlink(target: PathLike, path: PathLike, type: symlink.Type, callback: misc.TCallback<void>): any;
realpath(path: PathLike, callback: misc.TCallback<misc.TDataOut>): any;
realpath(path: PathLike, options: opts.IRealpathOptions | string, callback: misc.TCallback<misc.TDataOut>): any;
lstat(path: PathLike, callback: misc.TCallback<misc.IStats>): void;
lstat(path: PathLike, options: opts.IStatOptions, callback: misc.TCallback<misc.IStats>): void;
stat(path: PathLike, callback: misc.TCallback<misc.IStats>): void;
stat(path: PathLike, options: opts.IStatOptions, callback: misc.TCallback<misc.IStats>): void;
copyFile(src: misc.PathLike, dest: misc.PathLike, callback: misc.TCallback<void>): any;
copyFile(src: misc.PathLike, dest: misc.PathLike, flags: misc.TFlagsCopy, callback: misc.TCallback<void>): any;
link(existingPath: misc.PathLike, newPath: misc.PathLike, callback: misc.TCallback<void>): void;
unlink(path: misc.PathLike, callback: misc.TCallback<void>): void;
symlink(target: misc.PathLike, path: misc.PathLike, callback: misc.TCallback<void>): any;
symlink(target: misc.PathLike, path: misc.PathLike, type: misc.symlink.Type, callback: misc.TCallback<void>): any;
realpath(path: misc.PathLike, callback: misc.TCallback<misc.TDataOut>): any;
realpath(path: misc.PathLike, options: opts.IRealpathOptions | string, callback: misc.TCallback<misc.TDataOut>): any;
lstat(path: misc.PathLike, callback: misc.TCallback<misc.IStats>): void;
lstat(path: misc.PathLike, options: opts.IStatOptions, callback: misc.TCallback<misc.IStats>): void;
stat(path: misc.PathLike, callback: misc.TCallback<misc.IStats>): void;
stat(path: misc.PathLike, options: opts.IStatOptions, callback: misc.TCallback<misc.IStats>): void;
fstat(fd: number, callback: misc.TCallback<misc.IStats>): void;
fstat(fd: number, options: opts.IFStatOptions, callback: misc.TCallback<misc.IStats>): void;
rename(oldPath: PathLike, newPath: PathLike, callback: misc.TCallback<void>): void;
exists(path: PathLike, callback: (exists: boolean) => void): void;
access(path: PathLike, callback: misc.TCallback<void>): any;
access(path: PathLike, mode: number, callback: misc.TCallback<void>): any;
rename(oldPath: misc.PathLike, newPath: misc.PathLike, callback: misc.TCallback<void>): void;
exists(path: misc.PathLike, callback: (exists: boolean) => void): void;
access(path: misc.PathLike, callback: misc.TCallback<void>): any;
access(path: misc.PathLike, mode: number, callback: misc.TCallback<void>): any;
appendFile(id: misc.TFileId, data: misc.TData, callback: misc.TCallback<void>): any;
appendFile(id: misc.TFileId, data: misc.TData, options: opts.IAppendFileOptions | string, callback: misc.TCallback<void>): any;
readdir(path: PathLike, callback: misc.TCallback<misc.TDataOut[] | misc.IDirent[]>): any;
readdir(path: PathLike, options: opts.IReaddirOptions | string, callback: misc.TCallback<misc.TDataOut[] | misc.IDirent[]>): any;
readlink(path: PathLike, callback: misc.TCallback<misc.TDataOut>): any;
readlink(path: PathLike, options: opts.IOptions, callback: misc.TCallback<misc.TDataOut>): any;
fsyncSync(fd: number): void;
readdir(path: misc.PathLike, callback: misc.TCallback<misc.TDataOut[] | misc.IDirent[]>): any;
readdir(path: misc.PathLike, options: opts.IReaddirOptions | string, callback: misc.TCallback<misc.TDataOut[] | misc.IDirent[]>): any;
readlink(path: misc.PathLike, callback: misc.TCallback<misc.TDataOut>): any;
readlink(path: misc.PathLike, options: opts.IOptions, callback: misc.TCallback<misc.TDataOut>): any;
fsync(fd: number, callback: misc.TCallback<void>): void;

@@ -52,34 +41,44 @@ fdatasync(fd: number, callback: misc.TCallback<void>): void;

ftruncate(fd: number, len: number, callback: misc.TCallback<void>): any;
truncate(id: misc.TFileId, callback: misc.TCallback<void>): any;
truncate(id: misc.TFileId, len: number, callback: misc.TCallback<void>): any;
truncate(id: misc.PathLike, callback: misc.TCallback<void>): any;
truncate(id: misc.PathLike, len: number, callback: misc.TCallback<void>): any;
futimes(fd: number, atime: misc.TTime, mtime: misc.TTime, callback: misc.TCallback<void>): void;
utimes(path: PathLike, atime: misc.TTime, mtime: misc.TTime, callback: misc.TCallback<void>): void;
mkdir(path: PathLike, callback: misc.TCallback<void>): any;
mkdir(path: PathLike, mode: misc.TMode | (opts.IMkdirOptions & {
utimes(path: misc.PathLike, atime: misc.TTime, mtime: misc.TTime, callback: misc.TCallback<void>): void;
mkdir(path: misc.PathLike, callback: misc.TCallback<void>): any;
mkdir(path: misc.PathLike, mode: misc.TMode | (opts.IMkdirOptions & {
recursive?: false;
}), callback: misc.TCallback<void>): any;
mkdir(path: PathLike, mode: opts.IMkdirOptions & {
mkdir(path: misc.PathLike, mode: opts.IMkdirOptions & {
recursive: true;
}, callback: misc.TCallback<string>): any;
mkdir(path: PathLike, mode: misc.TMode | opts.IMkdirOptions, callback: misc.TCallback<string>): any;
mkdirp(path: PathLike, callback: misc.TCallback<string>): any;
mkdirp(path: PathLike, mode: misc.TMode, callback: misc.TCallback<string>): any;
mkdtemp(prefix: string, callback: misc.TCallback<void>): void;
mkdtemp(prefix: string, options: opts.IOptions, callback: misc.TCallback<void>): any;
rmdir(path: PathLike, callback: misc.TCallback<void>): any;
rmdir(path: PathLike, options: opts.IRmdirOptions, callback: misc.TCallback<void>): any;
rm(path: PathLike, callback: misc.TCallback<void>): void;
rm(path: PathLike, options: opts.IRmOptions, callback: misc.TCallback<void>): void;
mkdir(path: misc.PathLike, mode: misc.TMode | opts.IMkdirOptions, callback: misc.TCallback<string>): any;
mkdtemp(prefix: string, callback: misc.TCallback<string>): void;
mkdtemp(prefix: string, options: opts.IOptions, callback: misc.TCallback<string>): any;
rmdir(path: misc.PathLike, callback: misc.TCallback<void>): any;
rmdir(path: misc.PathLike, options: opts.IRmdirOptions, callback: misc.TCallback<void>): any;
rm(path: misc.PathLike, callback: misc.TCallback<void>): void;
rm(path: misc.PathLike, options: opts.IRmOptions, callback: misc.TCallback<void>): void;
fchmod(fd: number, mode: misc.TMode, callback: misc.TCallback<void>): void;
chmod(path: PathLike, mode: misc.TMode, callback: misc.TCallback<void>): void;
lchmod(path: PathLike, mode: misc.TMode, callback: misc.TCallback<void>): void;
chmod(path: misc.PathLike, mode: misc.TMode, callback: misc.TCallback<void>): void;
lchmod(path: misc.PathLike, mode: misc.TMode, callback: misc.TCallback<void>): void;
fchown(fd: number, uid: number, gid: number, callback: misc.TCallback<void>): void;
chown(path: PathLike, uid: number, gid: number, callback: misc.TCallback<void>): void;
lchown(path: PathLike, uid: number, gid: number, callback: misc.TCallback<void>): void;
watchFile(path: PathLike, listener: (curr: misc.IStats, prev: misc.IStats) => void): misc.IStatWatcher;
watchFile(path: PathLike, options: opts.IWatchFileOptions, listener: (curr: misc.IStats, prev: misc.IStats) => void): misc.IStatWatcher;
unwatchFile(path: PathLike, listener?: (curr: misc.IStats, prev: misc.IStats) => void): void;
createReadStream(path: PathLike, options?: opts.IReadStreamOptions | string): misc.IReadStream;
createWriteStream(path: PathLike, options?: opts.IWriteStreamOptions | string): misc.IWriteStream;
watch(path: PathLike, options?: opts.IWatchOptions | string, listener?: (eventType: string, filename: string) => void): misc.IFSWatcher;
chown(path: misc.PathLike, uid: number, gid: number, callback: misc.TCallback<void>): void;
lchown(path: misc.PathLike, uid: number, gid: number, callback: misc.TCallback<void>): void;
watchFile(path: misc.PathLike, listener: (curr: misc.IStats, prev: misc.IStats) => void): misc.IStatWatcher;
watchFile(path: misc.PathLike, options: opts.IWatchFileOptions, listener: (curr: misc.IStats, prev: misc.IStats) => void): misc.IStatWatcher;
unwatchFile(path: misc.PathLike, listener?: (curr: misc.IStats, prev: misc.IStats) => void): void;
createReadStream(path: misc.PathLike, options?: opts.IReadStreamOptions | string): misc.IReadStream;
createWriteStream(path: misc.PathLike, options?: opts.IWriteStreamOptions | string): misc.IWriteStream;
watch(path: misc.PathLike, options?: opts.IWatchOptions | string, listener?: (eventType: string, filename: string) => void): misc.IFSWatcher;
write(fd: number, buffer: Buffer | ArrayBufferView | DataView, callback: (...args: any[]) => void): any;
write(fd: number, buffer: Buffer | ArrayBufferView | DataView, offset: number, callback: (...args: any[]) => void): any;
write(fd: number, buffer: Buffer | ArrayBufferView | DataView, offset: number, length: number, callback: (...args: any[]) => void): any;
write(fd: number, buffer: Buffer | ArrayBufferView | DataView, offset: number, length: number, position: number, callback: (...args: any[]) => void): any;
write(fd: number, str: string, callback: (...args: any[]) => void): any;
write(fd: number, str: string, position: number, callback: (...args: any[]) => void): any;
write(fd: number, str: string, position: number, encoding: BufferEncoding, callback: (...args: any[]) => void): any;
writeFile(id: misc.TFileId, data: misc.TData, callback: misc.TCallback<void>): any;
writeFile(id: misc.TFileId, data: misc.TData, options: opts.IWriteFileOptions | string, callback: misc.TCallback<void>): any;
writev(fd: number, buffers: ArrayBufferView[], callback: WritevCallback): void;
writev(fd: number, buffers: ArrayBufferView[], position: number | null, callback: WritevCallback): void;
}
export type WritevCallback = (err: Error | null, bytesWritten?: number, buffers?: ArrayBufferView[]) => void;

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

import type { FsSynchronousApi } from './sync';
import type { FsSynchronousApi } from './FsSynchronousApi';
import type { FsCallbackApi } from './callback';

@@ -3,0 +3,0 @@ import type { FsPromisesApi } from './promises';

@@ -9,3 +9,3 @@ /// <reference types="node" />

import type { TSetTimeout } from '../../setTimeoutUnref';
import type { IAppendFileOptions, IReadFileOptions, IReadStreamOptions, IStatOptions, IWriteFileOptions, IWriteStreamOptions } from './options';
import type { IAppendFileOptions, IReadFileOptions, IStatOptions, IWriteFileOptions } from './options';
import type { Readable, Writable } from 'stream';

@@ -73,7 +73,5 @@ export { PathLike, symlink };

export interface IReadStream extends Readable {
new (path: PathLike, options: IReadStreamOptions): any;
open(): any;
close(callback: TCallback<void>): any;
bytesRead: number;
path: string;
path: string | Buffer;
pending: boolean;
}

@@ -83,5 +81,4 @@ export interface IWriteStream extends Writable {

path: string;
new (path: PathLike, options: IWriteStreamOptions): any;
open(): any;
close(): any;
pending: boolean;
close(callback?: (err?: Error) => void): void;
}

@@ -116,1 +113,2 @@ export interface IFSWatcher extends EventEmitter {

}
export type AssertCallback<T> = T extends () => void ? T : never;
/// <reference types="node" />
import type { TEncodingExtended, TFlags, TMode } from './misc';
import type { IFileHandle, TEncodingExtended, TFlags, TMode } from './misc';
export interface IOptions {

@@ -37,3 +37,2 @@ encoding?: BufferEncoding | TEncodingExtended;

export interface IRmdirOptions {
/** @deprecated */
recursive?: boolean;

@@ -53,17 +52,32 @@ maxRetries?: number;

}
export interface IReadStreamOptions {
export interface IReadStreamOptions extends IOptions {
/** Defaults to `'r'`. */
flags?: TFlags;
/** Defaults to `null`. */
encoding?: BufferEncoding;
fd?: number;
/** Defaults to `null`. */
fd?: number | IFileHandle | null;
/** Defaults to 0o666 */
mode?: TMode;
/** Defaults to `true`. */
autoClose?: boolean;
/** Defaults to `true`. */
emitClose?: boolean;
start?: number;
/** Defaults to `Infinity`. */
end?: number;
/** Defaults to `64 * 1024`. */
highWaterMark?: number;
/** Defaults to `null`. */
fs?: object | null;
/** Defaults to `null`. */
signal?: AbortSignal | null;
}
export interface IWriteStreamOptions {
flags?: TFlags;
defaultEncoding?: BufferEncoding;
fd?: number;
encoding?: BufferEncoding;
fd?: number | IFileHandle;
mode?: TMode;
autoClose?: boolean;
emitClose?: boolean;
start?: number;

@@ -70,0 +84,0 @@ }

@@ -15,5 +15,5 @@ /// <reference types="node" />

lstat(path: misc.PathLike, options?: opts.IStatOptions): Promise<misc.IStats>;
mkdir(path: misc.PathLike, options?: misc.TMode | opts.IMkdirOptions): Promise<void>;
mkdir(path: misc.PathLike, options?: misc.TMode | opts.IMkdirOptions): Promise<string | undefined>;
mkdtemp(prefix: string, options?: opts.IOptions): Promise<misc.TDataOut>;
open(path: misc.PathLike, flags: misc.TFlags, mode?: misc.TMode): Promise<misc.IFileHandle>;
open(path: misc.PathLike, flags?: misc.TFlags, mode?: misc.TMode): Promise<misc.IFileHandle>;
readdir(path: misc.PathLike, options?: opts.IReaddirOptions | string): Promise<misc.TDataOut[] | misc.IDirent[]>;

@@ -20,0 +20,0 @@ readFile(id: misc.TFileHandle, options?: opts.IReadFileOptions | string): Promise<misc.TDataOut>;

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

/// <reference types="node" />
/// <reference types="node" />
import type { FsCallbackApi } from './types';
import type * as misc from './types/misc';
import { TEncodingExtended } from '../encoding';
export declare const isWin: boolean;
export declare function promisify(fs: FsCallbackApi, fn: string, getResult?: (result: any) => any): (...args: any[]) => Promise<any>;
export declare function validateCallback<T>(callback: T): misc.AssertCallback<T>;
export declare function modeToNumber(mode: misc.TMode | undefined, def?: any): number;
export declare function nullCheck(path: any, callback?: any): boolean;
export declare function pathToFilename(path: misc.PathLike): string;
export declare function createError(errorCode: string, func?: string, path?: string, path2?: string, Constructor?: ErrorConstructor): Error;
export declare function genRndStr6(): string;
export declare function flagsToNumber(flags: misc.TFlags | undefined): number;
export declare function isFd(path: any): boolean;
export declare function validateFd(fd: any): void;
export declare function dataToBuffer(data: misc.TData, encoding?: string): Buffer;
export declare const bufToUint8: (buf: Buffer) => Uint8Array;
export declare const getWriteArgs: (fd: number, a?: unknown, b?: unknown, c?: unknown, d?: unknown, e?: unknown) => [fd: number, dataAsStr: boolean, buf: Buffer, offset: number, length: number, position: number | null, callback: (...args: any[]) => void];
export declare const getWriteSyncArgs: (fd: number, a: string | Buffer | ArrayBufferView | DataView, b?: number, c?: number | BufferEncoding, d?: number) => [fd: number, buf: Buffer, offset: number, length?: number | undefined, position?: number | undefined];
export declare function bufferToEncoding(buffer: Buffer, encoding?: TEncodingExtended): misc.TDataOut;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.promisify = void 0;
exports.bufferToEncoding = exports.getWriteSyncArgs = exports.getWriteArgs = exports.bufToUint8 = exports.dataToBuffer = exports.validateFd = exports.isFd = exports.flagsToNumber = exports.genRndStr6 = exports.createError = exports.pathToFilename = exports.nullCheck = exports.modeToNumber = exports.validateCallback = exports.promisify = exports.isWin = void 0;
const constants_1 = require("./constants");
const errors = require("../internal/errors");
const encoding_1 = require("../encoding");
const buffer_1 = require("../internal/buffer");
exports.isWin = process.platform === 'win32';
function promisify(fs, fn, getResult = input => input) {

@@ -14,1 +19,260 @@ return (...args) => new Promise((resolve, reject) => {

exports.promisify = promisify;
function validateCallback(callback) {
if (typeof callback !== 'function')
throw TypeError(constants_1.ERRSTR.CB);
return callback;
}
exports.validateCallback = validateCallback;
function _modeToNumber(mode, def) {
if (typeof mode === 'number')
return mode;
if (typeof mode === 'string')
return parseInt(mode, 8);
if (def)
return modeToNumber(def);
return undefined;
}
function modeToNumber(mode, def) {
const result = _modeToNumber(mode, def);
if (typeof result !== 'number' || isNaN(result))
throw new TypeError(constants_1.ERRSTR.MODE_INT);
return result;
}
exports.modeToNumber = modeToNumber;
function nullCheck(path, callback) {
if (('' + path).indexOf('\u0000') !== -1) {
const er = new Error('Path must be a string without null bytes');
er.code = 'ENOENT';
if (typeof callback !== 'function')
throw er;
process.nextTick(callback, er);
return false;
}
return true;
}
exports.nullCheck = nullCheck;
function getPathFromURLPosix(url) {
if (url.hostname !== '') {
throw new errors.TypeError('ERR_INVALID_FILE_URL_HOST', process.platform);
}
const pathname = url.pathname;
for (let n = 0; n < pathname.length; n++) {
if (pathname[n] === '%') {
const third = pathname.codePointAt(n + 2) | 0x20;
if (pathname[n + 1] === '2' && third === 102) {
throw new errors.TypeError('ERR_INVALID_FILE_URL_PATH', 'must not include encoded / characters');
}
}
}
return decodeURIComponent(pathname);
}
function pathToFilename(path) {
if (typeof path !== 'string' && !Buffer.isBuffer(path)) {
try {
if (!(path instanceof require('url').URL))
throw new TypeError(constants_1.ERRSTR.PATH_STR);
}
catch (err) {
throw new TypeError(constants_1.ERRSTR.PATH_STR);
}
path = getPathFromURLPosix(path);
}
const pathString = String(path);
nullCheck(pathString);
// return slash(pathString);
return pathString;
}
exports.pathToFilename = pathToFilename;
const ENOENT = 'ENOENT';
const EBADF = 'EBADF';
const EINVAL = 'EINVAL';
const EPERM = 'EPERM';
const EPROTO = 'EPROTO';
const EEXIST = 'EEXIST';
const ENOTDIR = 'ENOTDIR';
const EMFILE = 'EMFILE';
const EACCES = 'EACCES';
const EISDIR = 'EISDIR';
const ENOTEMPTY = 'ENOTEMPTY';
const ENOSYS = 'ENOSYS';
const ERR_FS_EISDIR = 'ERR_FS_EISDIR';
function formatError(errorCode, func = '', path = '', path2 = '') {
let pathFormatted = '';
if (path)
pathFormatted = ` '${path}'`;
if (path2)
pathFormatted += ` -> '${path2}'`;
switch (errorCode) {
case ENOENT:
return `ENOENT: no such file or directory, ${func}${pathFormatted}`;
case EBADF:
return `EBADF: bad file descriptor, ${func}${pathFormatted}`;
case EINVAL:
return `EINVAL: invalid argument, ${func}${pathFormatted}`;
case EPERM:
return `EPERM: operation not permitted, ${func}${pathFormatted}`;
case EPROTO:
return `EPROTO: protocol error, ${func}${pathFormatted}`;
case EEXIST:
return `EEXIST: file already exists, ${func}${pathFormatted}`;
case ENOTDIR:
return `ENOTDIR: not a directory, ${func}${pathFormatted}`;
case EISDIR:
return `EISDIR: illegal operation on a directory, ${func}${pathFormatted}`;
case EACCES:
return `EACCES: permission denied, ${func}${pathFormatted}`;
case ENOTEMPTY:
return `ENOTEMPTY: directory not empty, ${func}${pathFormatted}`;
case EMFILE:
return `EMFILE: too many open files, ${func}${pathFormatted}`;
case ENOSYS:
return `ENOSYS: function not implemented, ${func}${pathFormatted}`;
case ERR_FS_EISDIR:
return `[ERR_FS_EISDIR]: Path is a directory: ${func} returned EISDIR (is a directory) ${path}`;
default:
return `${errorCode}: error occurred, ${func}${pathFormatted}`;
}
}
function createError(errorCode, func = '', path = '', path2 = '', Constructor = Error) {
const error = new Constructor(formatError(errorCode, func, path, path2));
error.code = errorCode;
if (path) {
error.path = path;
}
return error;
}
exports.createError = createError;
function genRndStr6() {
const str = (Math.random() + 1).toString(36).substring(2, 8);
if (str.length === 6)
return str;
else
return genRndStr6();
}
exports.genRndStr6 = genRndStr6;
function flagsToNumber(flags) {
if (typeof flags === 'number')
return flags;
if (typeof flags === 'string') {
const flagsNum = constants_1.FLAGS[flags];
if (typeof flagsNum !== 'undefined')
return flagsNum;
}
// throw new TypeError(formatError(ERRSTR_FLAG(flags)));
throw new errors.TypeError('ERR_INVALID_OPT_VALUE', 'flags', flags);
}
exports.flagsToNumber = flagsToNumber;
function isFd(path) {
return path >>> 0 === path;
}
exports.isFd = isFd;
function validateFd(fd) {
if (!isFd(fd))
throw TypeError(constants_1.ERRSTR.FD);
}
exports.validateFd = validateFd;
function dataToBuffer(data, encoding = encoding_1.ENCODING_UTF8) {
if (Buffer.isBuffer(data))
return data;
else if (data instanceof Uint8Array)
return (0, buffer_1.bufferFrom)(data);
else
return (0, buffer_1.bufferFrom)(String(data), encoding);
}
exports.dataToBuffer = dataToBuffer;
const bufToUint8 = (buf) => new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
exports.bufToUint8 = bufToUint8;
const getWriteArgs = (fd, a, b, c, d, e) => {
validateFd(fd);
let offset = 0;
let length;
let position = null;
let encoding;
let callback;
const tipa = typeof a;
const tipb = typeof b;
const tipc = typeof c;
const tipd = typeof d;
if (tipa !== 'string') {
if (tipb === 'function') {
callback = b;
}
else if (tipc === 'function') {
offset = b | 0;
callback = c;
}
else if (tipd === 'function') {
offset = b | 0;
length = c;
callback = d;
}
else {
offset = b | 0;
length = c;
position = d;
callback = e;
}
}
else {
if (tipb === 'function') {
callback = b;
}
else if (tipc === 'function') {
position = b;
callback = c;
}
else if (tipd === 'function') {
position = b;
encoding = c;
callback = d;
}
}
const buf = dataToBuffer(a, encoding);
if (tipa !== 'string') {
if (typeof length === 'undefined')
length = buf.length;
}
else {
offset = 0;
length = buf.length;
}
const cb = validateCallback(callback);
return [fd, tipa === 'string', buf, offset, length, position, cb];
};
exports.getWriteArgs = getWriteArgs;
const getWriteSyncArgs = (fd, a, b, c, d) => {
validateFd(fd);
let encoding;
let offset;
let length;
let position;
const isBuffer = typeof a !== 'string';
if (isBuffer) {
offset = (b || 0) | 0;
length = c;
position = d;
}
else {
position = b;
encoding = c;
}
const buf = dataToBuffer(a, encoding);
if (isBuffer) {
if (typeof length === 'undefined') {
length = buf.length;
}
}
else {
offset = 0;
length = buf.length;
}
return [fd, buf, offset || 0, length, position];
};
exports.getWriteSyncArgs = getWriteSyncArgs;
function bufferToEncoding(buffer, encoding) {
if (!encoding || encoding === 'buffer')
return buffer;
else
return buffer.toString(encoding);
}
exports.bufferToEncoding = bufferToEncoding;

@@ -9,7 +9,10 @@ /// <reference types="node" />

import { TSetTimeout } from './setTimeoutUnref';
import { Readable, Writable } from 'stream';
import { Writable } from 'stream';
import { constants } from './constants';
import { EventEmitter } from 'events';
import { TEncodingExtended, TDataOut } from './encoding';
import { TDataOut } from './encoding';
import * as misc from './node/types/misc';
import * as opts from './node/types/options';
import type { PathLike, symlink } from 'fs';
import { FsCallbackApi, WritevCallback } from './node/types/callback';
export interface IError extends Error {

@@ -24,41 +27,5 @@ code?: string;

export type TCallback<TData> = (error?: IError | null, data?: TData) => void;
export declare enum FLAGS {
r,
'r+',
rs,
sr,
'rs+',
'sr+',
w,
wx,
xw,
'w+',
'wx+',
'xw+',
a,
ax,
xa,
'a+',
'ax+',
'xa+'
}
export type TFlagsCopy = typeof constants.COPYFILE_EXCL | typeof constants.COPYFILE_FICLONE | typeof constants.COPYFILE_FICLONE_FORCE;
export declare function flagsToNumber(flags: TFlags | undefined): number;
export interface IOptions {
encoding?: BufferEncoding | TEncodingExtended;
export interface IAppendFileOptions extends opts.IFileOptions {
}
export interface IFileOptions extends IOptions {
mode?: TMode;
flag?: TFlags;
}
export interface IReadFileOptions extends IOptions {
flag?: string;
}
export interface IWriteFileOptions extends IFileOptions {
}
export interface IAppendFileOptions extends IFileOptions {
}
export interface IRealpathOptions {
encoding?: TEncodingExtended;
}
export interface IWatchFileOptions {

@@ -68,55 +35,9 @@ persistent?: boolean;

}
export interface IReadStreamOptions {
flags?: TFlags;
encoding?: BufferEncoding;
fd?: number;
mode?: TMode;
autoClose?: boolean;
start?: number;
end?: number;
}
export interface IWriteStreamOptions {
flags?: TFlags;
defaultEncoding?: BufferEncoding;
fd?: number;
mode?: TMode;
autoClose?: boolean;
start?: number;
}
export interface IWatchOptions extends IOptions {
export interface IWatchOptions extends opts.IOptions {
persistent?: boolean;
recursive?: boolean;
}
export interface IMkdirOptions {
mode?: TMode;
recursive?: boolean;
}
export interface IRmdirOptions {
/** @deprecated */
recursive?: boolean;
maxRetries?: number;
retryDelay?: number;
}
export interface IRmOptions {
force?: boolean;
maxRetries?: number;
recursive?: boolean;
retryDelay?: number;
}
export interface IReaddirOptions extends IOptions {
withFileTypes?: boolean;
}
export interface IStatOptions {
bigint?: boolean;
throwIfNoEntry?: boolean;
}
export interface IFStatOptions {
bigint?: boolean;
}
export declare function pathToFilename(path: PathLike): string;
export declare function filenameToSteps(filename: string, base?: string): string[];
export declare function pathToSteps(path: PathLike): string[];
export declare function dataToStr(data: TData, encoding?: string): string;
export declare function dataToBuffer(data: TData, encoding?: string): Buffer;
export declare function bufferToEncoding(buffer: Buffer, encoding?: TEncodingExtended): TDataOut;
export declare function toUnixTimestamp(time: any): any;

@@ -133,3 +54,3 @@ type DirectoryContent = string | null;

*/
export declare class Volume {
export declare class Volume implements FsCallbackApi {
static fromJSON(json: DirectoryJSON, cwd?: string): Volume;

@@ -158,3 +79,3 @@ static fromNestedJSON(json: NestedDirectoryJSON, cwd?: string): Volume;

StatWatcher: new () => StatWatcher;
ReadStream: new (...args: any[]) => IReadStream;
ReadStream: new (...args: any[]) => misc.IReadStream;
WriteStream: new (...args: any[]) => IWriteStream;

@@ -176,5 +97,3 @@ FSWatcher: new () => FSWatcher;

createNode(isDirectory?: boolean, perm?: number): Node;
private getNode;
private deleteNode;
genRndStr(): any;
getLink(steps: string[]): Link | null;

@@ -214,5 +133,5 @@ getLinkOrThrow(filename: string, funcName?: string): Link;

private readFileBase;
readFileSync(file: TFileId, options?: IReadFileOptions | string): TDataOut;
readFileSync(file: TFileId, options?: opts.IReadFileOptions | string): TDataOut;
readFile(id: TFileId, callback: TCallback<TDataOut>): any;
readFile(id: TFileId, options: IReadFileOptions | string, callback: TCallback<TDataOut>): any;
readFile(id: TFileId, options: opts.IReadFileOptions | string, callback: TCallback<TDataOut>): any;
private writeBase;

@@ -228,6 +147,8 @@ writeSync(fd: number, buffer: Buffer | ArrayBufferView | DataView, offset?: number, length?: number, position?: number): number;

write(fd: number, str: string, position: number, encoding: BufferEncoding, callback: (...args: any[]) => void): any;
writev(fd: number, buffers: ArrayBufferView[], callback: WritevCallback): void;
writev(fd: number, buffers: ArrayBufferView[], position: number | null, callback: WritevCallback): void;
private writeFileBase;
writeFileSync(id: TFileId, data: TData, options?: IWriteFileOptions): void;
writeFileSync(id: TFileId, data: TData, options?: opts.IWriteFileOptions): void;
writeFile(id: TFileId, data: TData, callback: TCallback<void>): any;
writeFile(id: TFileId, data: TData, options: IWriteFileOptions | string, callback: TCallback<void>): any;
writeFile(id: TFileId, data: TData, options: opts.IWriteFileOptions | string, callback: TCallback<void>): any;
private linkBase;

@@ -248,5 +169,5 @@ private copyFileBase;

private realpathBase;
realpathSync(path: PathLike, options?: IRealpathOptions | string): TDataOut;
realpathSync(path: PathLike, options?: opts.IRealpathOptions | string): TDataOut;
realpath(path: PathLike, callback: TCallback<TDataOut>): any;
realpath(path: PathLike, options: IRealpathOptions | string, callback: TCallback<TDataOut>): any;
realpath(path: PathLike, options: opts.IRealpathOptions | string, callback: TCallback<TDataOut>): any;
private lstatBase;

@@ -277,3 +198,3 @@ lstatSync(path: PathLike): Stats<number>;

lstat(path: PathLike, callback: TCallback<Stats>): void;
lstat(path: PathLike, options: IStatOptions, callback: TCallback<Stats>): void;
lstat(path: PathLike, options: opts.IStatOptions, callback: TCallback<Stats>): void;
private statBase;

@@ -304,3 +225,3 @@ statSync(path: PathLike): Stats<number>;

stat(path: PathLike, callback: TCallback<Stats>): void;
stat(path: PathLike, options: IStatOptions, callback: TCallback<Stats>): void;
stat(path: PathLike, options: opts.IStatOptions, callback: TCallback<Stats>): void;
private fstatBase;

@@ -315,3 +236,3 @@ fstatSync(fd: number): Stats<number>;

fstat(fd: number, callback: TCallback<Stats>): void;
fstat(fd: number, options: IFStatOptions, callback: TCallback<Stats>): void;
fstat(fd: number, options: opts.IFStatOptions, callback: TCallback<Stats>): void;
private renameBase;

@@ -331,9 +252,9 @@ renameSync(oldPath: PathLike, newPath: PathLike): void;

private readdirBase;
readdirSync(path: PathLike, options?: IReaddirOptions | string): TDataOut[] | Dirent[];
readdirSync(path: PathLike, options?: opts.IReaddirOptions | string): TDataOut[] | Dirent[];
readdir(path: PathLike, callback: TCallback<TDataOut[] | Dirent[]>): any;
readdir(path: PathLike, options: IReaddirOptions | string, callback: TCallback<TDataOut[] | Dirent[]>): any;
readdir(path: PathLike, options: opts.IReaddirOptions | string, callback: TCallback<TDataOut[] | Dirent[]>): any;
private readlinkBase;
readlinkSync(path: PathLike, options?: IOptions): TDataOut;
readlinkSync(path: PathLike, options?: opts.IOptions): TDataOut;
readlink(path: PathLike, callback: TCallback<TDataOut>): any;
readlink(path: PathLike, options: IOptions, callback: TCallback<TDataOut>): any;
readlink(path: PathLike, options: opts.IOptions, callback: TCallback<TDataOut>): any;
private fsyncBase;

@@ -350,2 +271,6 @@ fsyncSync(fd: number): void;

private truncateBase;
/**
* `id` should be a file descriptor or a path. `id` as file descriptor will
* not be supported soon.
*/
truncateSync(id: TFileId, len?: number): void;

@@ -367,17 +292,17 @@ truncate(id: TFileId, callback: TCallback<void>): any;

private mkdirpBase;
mkdirSync(path: PathLike, options: IMkdirOptions & {
mkdirSync(path: PathLike, options: opts.IMkdirOptions & {
recursive: true;
}): string | undefined;
mkdirSync(path: PathLike, options?: TMode | (IMkdirOptions & {
mkdirSync(path: PathLike, options?: TMode | (opts.IMkdirOptions & {
recursive?: false;
})): void;
mkdirSync(path: PathLike, options?: TMode | IMkdirOptions): string | undefined;
mkdirSync(path: PathLike, options?: TMode | opts.IMkdirOptions): string | undefined;
mkdir(path: PathLike, callback: TCallback<void>): any;
mkdir(path: PathLike, mode: TMode | (IMkdirOptions & {
mkdir(path: PathLike, mode: TMode | (opts.IMkdirOptions & {
recursive?: false;
}), callback: TCallback<void>): any;
mkdir(path: PathLike, mode: IMkdirOptions & {
mkdir(path: PathLike, mode: opts.IMkdirOptions & {
recursive: true;
}, callback: TCallback<string>): any;
mkdir(path: PathLike, mode: TMode | IMkdirOptions, callback: TCallback<string>): any;
mkdir(path: PathLike, mode: TMode | opts.IMkdirOptions, callback: TCallback<string>): any;
mkdirpSync(path: PathLike, mode?: TMode): string | undefined;

@@ -387,13 +312,13 @@ mkdirp(path: PathLike, callback: TCallback<string>): any;

private mkdtempBase;
mkdtempSync(prefix: string, options?: IOptions): TDataOut;
mkdtemp(prefix: string, callback: TCallback<void>): any;
mkdtemp(prefix: string, options: IOptions, callback: TCallback<void>): any;
mkdtempSync(prefix: string, options?: opts.IOptions): TDataOut;
mkdtemp(prefix: string, callback: TCallback<string>): any;
mkdtemp(prefix: string, options: opts.IOptions, callback: TCallback<string>): any;
private rmdirBase;
rmdirSync(path: PathLike, options?: IRmdirOptions): void;
rmdirSync(path: PathLike, options?: opts.IRmdirOptions): void;
rmdir(path: PathLike, callback: TCallback<void>): any;
rmdir(path: PathLike, options: IRmdirOptions, callback: TCallback<void>): any;
rmdir(path: PathLike, options: opts.IRmdirOptions, callback: TCallback<void>): any;
private rmBase;
rmSync(path: PathLike, options?: IRmOptions): void;
rmSync(path: PathLike, options?: opts.IRmOptions): void;
rm(path: PathLike, callback: TCallback<void>): void;
rm(path: PathLike, options: IRmOptions, callback: TCallback<void>): void;
rm(path: PathLike, options: opts.IRmOptions, callback: TCallback<void>): void;
private fchmodBase;

@@ -421,4 +346,4 @@ fchmodSync(fd: number, mode: TMode): void;

unwatchFile(path: PathLike, listener?: (curr: Stats, prev: Stats) => void): void;
createReadStream(path: PathLike, options?: IReadStreamOptions | string): IReadStream;
createWriteStream(path: PathLike, options?: IWriteStreamOptions | string): IWriteStream;
createReadStream(path: misc.PathLike, options?: opts.IReadStreamOptions | string): misc.IReadStream;
createWriteStream(path: PathLike, options?: opts.IWriteStreamOptions | string): IWriteStream;
watch(path: PathLike, options?: IWatchOptions | string, listener?: (eventType: string, filename: string) => void): FSWatcher;

@@ -440,13 +365,7 @@ }

}
export interface IReadStream extends Readable {
new (path: PathLike, options: IReadStreamOptions): any;
open(): any;
close(callback: TCallback<void>): any;
bytesRead: number;
path: string;
}
export interface IWriteStream extends Writable {
bytesWritten: number;
path: string;
new (path: PathLike, options: IWriteStreamOptions): any;
pending: boolean;
new (path: PathLike, options: opts.IWriteStreamOptions): any;
open(): any;

@@ -453,0 +372,0 @@ close(): any;

{
"name": "memfs",
"version": "4.0.0",
"version": "4.1.0-next.1",
"description": "In-memory file-system with Node's fs API.",

@@ -25,3 +25,3 @@ "keywords": [

},
"license": "Unlicense",
"license": "Apache-2.0",
"main": "lib/index.js",

@@ -42,3 +42,9 @@ "types": "lib/index.d.ts",

"typecheck": "tsc -p .",
"watch": "watch \"npm run build\" ./src"
"watch": "watch \"npm run build\" ./src",
"build:webfs": "NODE_ENV=production webpack --config ./src/webfs/webpack.config.js",
"demo:webfs": "webpack serve --config ./src/webfs/webpack.config.js",
"demo:fsa-to-node-sync-tests": "webpack serve --config ./demo/fsa-to-node-sync-tests/webpack.config.js",
"demo:fsa-to-node-zipfile": "webpack serve --config ./demo/fsa-to-node-zipfile/webpack.config.js",
"demo:git-fsa": "webpack serve --config ./demo/git-fsa/webpack.config.js",
"demo:git-opfs": "webpack serve --config ./demo/git-opfs/webpack.config.js"
},

@@ -56,2 +62,9 @@ "commitlint": {

"release": {
"branches": [
"master",
{
"name": "next",
"prerelease": true
}
],
"prepare": [

@@ -82,3 +95,5 @@ "@semantic-release/changelog",

"dependencies": {
"fs-monkey": "^1.0.4"
"fs-monkey": "^1.0.4",
"json-joy": "^9.2.0",
"thingies": "^1.11.1"
},

@@ -91,13 +106,28 @@ "devDependencies": {

"@types/node": "^10.17.60",
"app-root-path": "^3.1.0",
"assert": "^2.0.0",
"buffer": "^6.0.3",
"html-webpack-plugin": "^5.5.3",
"husky": "^8.0.1",
"isomorphic-git": "^1.24.2",
"jest": "^28.1.1",
"path-browserify": "^1.0.1",
"prettier": "^2.7.1",
"pretty-quick": "^3.1.3",
"process": "^0.11.10",
"readable-stream": "^4.4.0",
"rimraf": "^3.0.2",
"semantic-release": "^19.0.3",
"tar-stream": "^3.1.2",
"ts-jest": "^28.0.5",
"ts-loader": "^9.4.3",
"ts-node": "^10.8.1",
"tslint": "^5.20.1",
"tslint-config-common": "^1.6.0",
"typescript": "^4.7.4"
"typescript": "^4.7.4",
"url": "^0.11.1",
"util": "^0.12.5",
"webpack": "^5.87.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
},

@@ -104,0 +134,0 @@ "engines": {

# memfs
[![][chat-badge]][chat] [![][npm-badge]][npm-url] [![][travis-badge]][travis-url]
[![][chat-badge]][chat] [![][npm-badge]][npm-url]
In-memory file-system with [Node's `fs` API](https://nodejs.org/api/fs.html).
[chat]: https://onp4.com/@vadim/~memfs
[chat-badge]: https://img.shields.io/badge/Chat-%F0%9F%92%AC-green?style=flat&logo=chat&link=https://onp4.com/@vadim/~memfs
[npm-url]: https://www.npmjs.com/package/memfs
[npm-badge]: https://img.shields.io/npm/v/memfs.svg
- Node's `fs` API implemented, see [_old API Status_](./docs/api-status.md), [missing list](https://github.com/streamich/memfs/issues/735), [missing `opendir`](https://github.com/streamich/memfs/issues/663)
- Stores files in memory, in `Buffer`s
- Throws sameish\* errors as Node.js
- Has concept of _i-nodes_
- Implements _hard links_
- Implements _soft links_ (aka symlinks, symbolic links)
- Permissions may\* be implemented in the future
- Can be used in browser, see [`memfs-webpack`](https://github.com/streamich/memfs-webpack)
JavaScript file system utilities for Node.js and browser.
### Install
## Install
```shell
npm install --save memfs
npm i memfs
```
## Usage
```js
import { fs } from 'memfs';
## Docs
fs.writeFileSync('/hello.txt', 'World!');
fs.readFileSync('/hello.txt', 'utf8'); // World!
```
- [In-memory Node.js `fs` API](./docs/node/index.md)
- `experimental` [`fs` to File System Access API adapter](./docs/fsa/fs-to-fsa.md)
- `experimental` [File System Access API to `fs` adapter](./docs/fsa/fsa-to-fs.md)
- `experimental` [`crudfs` a CRUD-like file system abstraction](./docs/crudfs/index.md)
Create a file system from a plain JSON:
```js
import { fs, vol } from 'memfs';
## Demos
const json = {
'./README.md': '1',
'./src/index.js': '2',
'./node_modules/debug/index.js': '3',
};
vol.fromJSON(json, '/app');
- [Git in browser, which writes to a real folder](demo/git-fsa/README.md)
- [Git in browser, which writes to OPFS file system](demo/git-opfs/README.md)
- [Git on in-memory file system](demo/git/README.md)
- [`fs` in browser, creates a `.tar` file in real folder](demo/fsa-to-node-zipfile/README.md)
- [`fs` in browser, synchronous API, writes to real folder](demo/fsa-to-node-sync-tests/README.md)
fs.readFileSync('/app/README.md', 'utf8'); // 1
vol.readFileSync('/app/src/index.js', 'utf8'); // 2
```
Export to JSON:
```js
vol.writeFileSync('/script.sh', 'sudo rm -rf *');
vol.toJSON(); // {"/script.sh": "sudo rm -rf *"}
```
Use it for testing:
```js
vol.writeFileSync('/foo', 'bar');
expect(vol.toJSON()).toEqual({ '/foo': 'bar' });
```
Create as many filesystem volumes as you need:
```js
import { Volume } from 'memfs';
const vol = Volume.fromJSON({ '/foo': 'bar' });
vol.readFileSync('/foo'); // bar
const vol2 = Volume.fromJSON({ '/foo': 'bar 2' });
vol2.readFileSync('/foo'); // bar 2
```
Use `memfs` together with [`unionfs`][unionfs] to create one filesystem
from your in-memory volumes and the real disk filesystem:
```js
import * as fs from 'fs';
import { ufs } from 'unionfs';
ufs.use(fs).use(vol);
ufs.readFileSync('/foo'); // bar
```
Use [`fs-monkey`][fs-monkey] to monkey-patch Node's `require` function:
```js
import { patchRequire } from 'fs-monkey';
vol.writeFileSync('/index.js', 'console.log("hi world")');
patchRequire(vol);
require('/index'); // hi world
```
## Docs
- [Reference](./docs/reference.md)
- [Relative paths](./docs/relative-paths.md)
- [API status](./docs/api-status.md)
- [Dependencies](./docs/dependencies.md)
## See also

@@ -108,18 +43,11 @@

- [`fs-monkey`][fs-monkey] - monkey-patches Node's `fs` module and `require` function
- [`libfs`](https://github.com/streamich/full-js/blob/master/src/lib/fs.ts) - real filesystem (that executes UNIX system calls) implemented in JavaScript
[chat]: https://onp4.com/@vadim/~memfs
[chat-badge]: https://img.shields.io/badge/Chat-%F0%9F%92%AC-green?style=flat&logo=chat&link=https://onp4.com/@vadim/~memfs
[npm-url]: https://www.npmjs.com/package/memfs
[npm-badge]: https://img.shields.io/npm/v/memfs.svg
[travis-url]: https://travis-ci.org/streamich/memfs
[travis-badge]: https://travis-ci.org/streamich/memfs.svg?branch=master
[memfs]: https://github.com/streamich/memfs
[spyfs]: https://github.com/streamich/spyfs
[unionfs]: https://github.com/streamich/unionfs
[linkfs]: https://github.com/streamich/linkfs
[spyfs]: https://github.com/streamich/spyfs
[fs-monkey]: https://github.com/streamich/fs-monkey
## License
[Unlicense](./LICENSE) - public domain.
Apache 2.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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc