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.5.4 to 0.5.5

17

dist/ApiError.d.ts

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

message: string;
path: string;
path?: string;
code: string;
stack: string;
syscall: string;
}

@@ -95,14 +96,6 @@ /**

path?: string;
syscall: string;
static fromJSON(json: ApiErrorJSON): ApiError;
static OnPath(code: ErrorCode, path: string): ApiError;
static EACCES(path: string): ApiError;
static ENOENT(path: string): ApiError;
static EEXIST(path: string): ApiError;
static EISDIR(path: string): ApiError;
static ENOTDIR(path: string): ApiError;
static EPERM(path: string): ApiError;
static ENOTEMPTY(path: string): ApiError;
static With(code: string, path: string, syscall?: string): ApiError;
code: string;
syscall: string;
stack?: string;
/**

@@ -118,3 +111,3 @@ * Represents a ZenFS error. Passed back to applications after a failed

*/
constructor(errno: ErrorCode, message?: string, path?: string);
constructor(errno: ErrorCode, message?: string, path?: string, syscall?: string);
/**

@@ -121,0 +114,0 @@ * @return A friendly error message.

@@ -101,3 +101,3 @@ /**

static fromJSON(json) {
const err = new ApiError(json.errno, json.message, json.path);
const err = new ApiError(json.errno, json.message, json.path, json.syscall);
err.code = json.code;

@@ -107,26 +107,5 @@ err.stack = json.stack;

}
static OnPath(code, path) {
return new ApiError(code, ErrorStrings[code], path);
static With(code, path, syscall) {
return new ApiError(ErrorCode[code], ErrorStrings[ErrorCode[code]], path, syscall);
}
static EACCES(path) {
return this.OnPath(ErrorCode.EACCES, path);
}
static ENOENT(path) {
return this.OnPath(ErrorCode.ENOENT, path);
}
static EEXIST(path) {
return this.OnPath(ErrorCode.EEXIST, path);
}
static EISDIR(path) {
return this.OnPath(ErrorCode.EISDIR, path);
}
static ENOTDIR(path) {
return this.OnPath(ErrorCode.ENOTDIR, path);
}
static EPERM(path) {
return this.OnPath(ErrorCode.EPERM, path);
}
static ENOTEMPTY(path) {
return this.OnPath(ErrorCode.ENOTEMPTY, path);
}
/**

@@ -142,8 +121,7 @@ * Represents a ZenFS error. Passed back to applications after a failed

*/
constructor(errno, message = ErrorStrings[errno], path) {
constructor(errno, message = ErrorStrings[errno], path, syscall = '') {
super(message);
this.errno = errno;
this.path = path;
// Unsupported.
this.syscall = '';
this.syscall = syscall;
this.code = ErrorCode[errno];

@@ -165,2 +143,3 @@ this.message = `${this.code}: ${message}${this.path ? `, '${this.path}'` : ''}`;

message: this.message,
syscall: this.syscall,
};

@@ -167,0 +146,0 @@ }

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

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

@@ -172,3 +172,3 @@ const nodeId = oldDirList[oldName];

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

@@ -198,7 +198,7 @@ }

if (!inode) {
throw ApiError.ENOENT(p);
throw ApiError.With('ENOENT', p, 'stat');
}
const stats = inode.toStats();
if (!stats.hasAccess(R_OK, cred)) {
throw ApiError.EACCES(p);
throw ApiError.With('EACCES', p, 'stat');
}

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

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

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

if (list.length > 0) {
throw ApiError.ENOTEMPTY(p);
throw ApiError.With('ENOTEMPTY', p, 'rmdir');
}

@@ -243,3 +243,3 @@ await this.removeEntry(p, true, cred);

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

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

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

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

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

@@ -352,3 +352,3 @@ node.nlink++;

else {
throw ApiError.ENOENT(resolve(parent, filename));
throw ApiError.With('ENOENT', resolve(parent, filename), '_findINode');
}

@@ -370,3 +370,3 @@ }

else {
throw ApiError.ENOENT(resolve(parent, filename));
throw ApiError.With('ENOENT', resolve(parent, filename), '_findINode');
}

@@ -393,3 +393,3 @@ }

if (!data) {
throw ApiError.ENOENT(p);
throw ApiError.With('ENOENT', p, 'getINode');
}

@@ -404,3 +404,3 @@ return new Inode(data.buffer);

if (!inode.toStats().isDirectory()) {
throw ApiError.ENOTDIR(p);
throw ApiError.With('ENOTDIR', p, 'getDirListing');
}

@@ -414,3 +414,3 @@ const data = await tx.get(inode.ino);

*/
throw ApiError.ENOENT(p);
throw ApiError.With('ENOENT', p, 'getDirListing');
}

@@ -450,3 +450,3 @@ return decodeDirListing(data);

if (!parentNode.toStats().hasAccess(W_OK, cred)) {
throw ApiError.EACCES(p);
throw ApiError.With('EACCES', p, 'commitNewFile');
}

@@ -457,3 +457,3 @@ // Invariant: The root always exists.

if (p === '/') {
throw ApiError.EEXIST(p);
throw ApiError.With('EEXIST', p, 'commitNewFile');
}

@@ -463,3 +463,3 @@ // Check if file already exists.

await tx.abort();
throw ApiError.EEXIST(p);
throw ApiError.With('EEXIST', p, 'commitNewFile');
}

@@ -503,3 +503,3 @@ try {

if (!parentListing[fileName]) {
throw ApiError.ENOENT(p);
throw ApiError.With('ENOENT', p, 'removeEntry');
}

@@ -510,3 +510,3 @@ const fileIno = parentListing[fileName];

if (!fileNode.toStats().hasAccess(W_OK, cred)) {
throw ApiError.EACCES(p);
throw ApiError.With('EACCES', p, 'removeEntry');
}

@@ -516,6 +516,6 @@ // Remove from directory listing of parent.

if (!isDir && fileNode.toStats().isDirectory()) {
throw ApiError.EISDIR(p);
throw ApiError.With('EISDIR', p, 'removeEntry');
}
if (isDir && !fileNode.toStats().isDirectory()) {
throw ApiError.ENOTDIR(p);
throw ApiError.With('ENOTDIR', p, 'removeEntry');
}

@@ -522,0 +522,0 @@ try {

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

*/
export interface BackendConfig {
backend: Backend;
export interface BackendConfig<FS extends FileSystem = FileSystem, OC extends BackendOptionsConfig = BackendOptionsConfig> {
backend: Backend<FS, OC>;
[key: string]: unknown;

@@ -89,3 +89,3 @@ }

*/
export declare function resolveBackend(options: BackendConfig, _depth?: number): Promise<FileSystem>;
export declare function resolveBackend<FS extends FileSystem>(options: BackendConfig<FS>, _depth?: number): Promise<FS>;
export {};

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

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

@@ -151,3 +151,3 @@ }

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

@@ -163,3 +163,3 @@ }

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

@@ -179,3 +179,3 @@ const oldStat = new Stats(await this._readable.stat(p, cred));

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

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

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

@@ -246,3 +246,3 @@ if (await this._writable.exists(p, cred)) {

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

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

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

@@ -269,3 +269,3 @@ if (await this._writable.exists(p, cred)) {

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

@@ -280,3 +280,3 @@ else {

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

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

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

@@ -300,3 +300,3 @@ else {

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

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

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

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

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

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

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

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

if (path == deletionLogPath) {
throw ApiError.EPERM(path);
throw ApiError.With('EPERM', path, 'checkPath');
}

@@ -460,3 +460,3 @@ }

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

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

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

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

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

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

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

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

@@ -199,3 +199,3 @@ }

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

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

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

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

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

@@ -239,3 +239,3 @@ else {

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

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

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

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

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

@@ -325,3 +325,3 @@ node.nlink++;

if (!(filename in dir)) {
throw ApiError.ENOENT(resolve(parent, filename));
throw ApiError.With('ENOENT', resolve(parent, filename), '_findINode');
}

@@ -334,3 +334,3 @@ return dir[filename];

if (!(filename in dir)) {
throw ApiError.ENOENT(resolve(parent, filename));
throw ApiError.With('ENOENT', resolve(parent, filename), '_findINode');
}

@@ -361,3 +361,3 @@ return dir[filename];

if (!data) {
throw ApiError.ENOENT(p);
throw ApiError.With('ENOENT', p, 'getINode');
}

@@ -372,7 +372,7 @@ const inode = new Inode(data.buffer);

if (!inode.toStats().isDirectory()) {
throw ApiError.ENOTDIR(p);
throw ApiError.With('ENOTDIR', p, 'getDirListing');
}
const data = tx.get(inode.ino);
if (!data) {
throw ApiError.ENOENT(p);
throw ApiError.With('ENOENT', p, 'getDirListing');
}

@@ -409,3 +409,3 @@ return decodeDirListing(data);

if (!parentNode.toStats().hasAccess(W_OK, cred)) {
throw ApiError.EACCES(p);
throw ApiError.With('EACCES', p, 'commitNewFile');
}

@@ -417,7 +417,7 @@ /* Invariant: The root always exists.

if (p === '/') {
throw ApiError.EEXIST(p);
throw ApiError.With('EEXIST', p, 'commitNewFile');
}
// Check if file already exists.
if (dirListing[fname]) {
throw ApiError.EEXIST(p);
throw ApiError.With('EEXIST', p, 'commitNewFile');
}

@@ -452,3 +452,3 @@ const fileNode = new Inode();

if (!fileIno) {
throw ApiError.ENOENT(p);
throw ApiError.With('ENOENT', p, 'removeEntry');
}

@@ -458,3 +458,3 @@ // Get file inode.

if (!fileNode.toStats().hasAccess(W_OK, cred)) {
throw ApiError.EACCES(p);
throw ApiError.With('EACCES', p, 'removeEntry');
}

@@ -464,6 +464,6 @@ // Remove from directory listing of parent.

if (!isDir && fileNode.toStats().isDirectory()) {
throw ApiError.EISDIR(p);
throw ApiError.With('EISDIR', p, 'removeEntry');
}
if (isDir && !fileNode.toStats().isDirectory()) {
throw ApiError.ENOTDIR(p);
throw ApiError.With('ENOTDIR', p, 'removeEntry');
}

@@ -470,0 +470,0 @@ try {

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

}): Promise<Uint8Array>;
export declare function readFile(filename: PathLike, options: {
encoding?: BufferEncoding;
export declare function readFile(filename: PathLike, options: (Node.BaseEncodingOptions & {
flag?: Node.OpenMode;
} | BufferEncoding): Promise<string>;
}) | BufferEncoding): Promise<string>;
/**

@@ -223,0 +222,0 @@ * Synchronously writes data to a file, replacing the file if it already exists.

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

import { dirname, join } from './path.js';
import { F_OK } from './constants.js';
export class FileHandle {

@@ -102,3 +103,3 @@ constructor(

async readFile(_options) {
const options = normalizeOptions(_options, null, 'r', null);
const options = normalizeOptions(_options, null, 'r', 0o444);
const flag = parseFlag(options.flag);

@@ -213,11 +214,14 @@ if (!isReadable(flag)) {

newPath = normalizePath(newPath);
const { path: old } = resolveFS(oldPath);
const { fs, path } = resolveFS(newPath);
const src = resolveFS(oldPath);
const dst = resolveFS(newPath);
try {
const data = await readFile(oldPath);
await writeFile(newPath, data);
if (src.mountPoint == dst.mountPoint) {
await src.fs.rename(src.path, dst.path, cred);
return;
}
await writeFile(newPath, await readFile(oldPath));
await unlink(oldPath);
}
catch (e) {
throw fixError(e, { [old]: oldPath, [path]: newPath });
throw fixError(e, { [src.path]: oldPath, [dst.path]: newPath });
}

@@ -285,3 +289,3 @@ }

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

@@ -314,7 +318,7 @@ /*

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

@@ -535,3 +539,3 @@ throw new ApiError(ErrorCode.EINVAL, 'Invalid file flag');

if (await exists(path)) {
throw ApiError.EEXIST(path);
throw ApiError.With('EEXIST', path, 'symlink');
}

@@ -677,3 +681,3 @@ await writeFile(path, target);

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

@@ -680,0 +684,0 @@ if (!stats.hasAccess(mode, cred)) {

/// <reference types="node" resolution-mode="require"/>
/// <reference types="node" resolution-mode="require"/>
import { Cred } from '../cred.js';
import { FileSystem } from '../filesystem.js';
import type { File } from '../file.js';
import type { BaseEncodingOptions, OpenMode, WriteFileOptions } from 'node:fs';
/**

@@ -29,5 +31,11 @@ * converts Date or number to a integer UNIX timestamp

* Normalizes options
* @param options options to normalize
* @param encoding default encoding
* @param flag default flag
* @param mode default mode
* @internal
*/
export declare function normalizeOptions(options: unknown, defEnc: string | null, defFlag: string, defMode: number | null): {
export declare function normalizeOptions(options?: WriteFileOptions | (BaseEncodingOptions & {
flag?: OpenMode;
}), encoding?: BufferEncoding, flag?: string, mode?: number): {
encoding: BufferEncoding;

@@ -34,0 +42,0 @@ flag: string;

@@ -26,13 +26,11 @@ // Utilities and shared data

export function normalizeMode(mode, def) {
switch (typeof mode) {
case 'number':
// (path, flag, mode, cb?)
return mode;
case 'string':
// (path, flag, modeString, cb?)
const trueMode = parseInt(mode, 8);
if (!isNaN(trueMode)) {
return trueMode;
}
if (typeof mode == 'number') {
return mode;
}
if (typeof mode == 'string') {
const parsed = parseInt(mode, 8);
if (!isNaN(parsed)) {
return parsed;
}
}
if (typeof def == 'number') {

@@ -65,41 +63,31 @@ return def;

// Node doesn't allow null characters in paths.
if (p.indexOf('\u0000') >= 0) {
if (p.includes('\x00')) {
throw new ApiError(ErrorCode.EINVAL, 'Path must be a string without null bytes.');
}
if (p === '') {
if (p.length == 0) {
throw new ApiError(ErrorCode.EINVAL, 'Path must not be empty.');
}
p = p.replaceAll(/\/+/g, '/');
return resolve(p);
return resolve(p.replaceAll(/[/\\]+/g, '/'));
}
/**
* Normalizes options
* @param options options to normalize
* @param encoding default encoding
* @param flag default flag
* @param mode default mode
* @internal
*/
export function normalizeOptions(options, defEnc, defFlag, defMode) {
// typeof null === 'object' so special-case handing is needed.
switch (options === null ? 'null' : typeof options) {
case 'object':
return {
encoding: typeof options['encoding'] !== 'undefined' ? options['encoding'] : defEnc,
flag: typeof options['flag'] !== 'undefined' ? options['flag'] : defFlag,
mode: normalizeMode(options['mode'], defMode),
};
case 'string':
return {
encoding: options,
flag: defFlag,
mode: defMode,
};
case 'null':
case 'undefined':
case 'function':
return {
encoding: defEnc,
flag: defFlag,
mode: defMode,
};
default:
throw new TypeError(`"options" must be a string or an object, got ${typeof options} instead.`);
export function normalizeOptions(options, encoding = 'utf8', flag, mode = 0) {
if (typeof options != 'object' || options === null) {
return {
encoding: typeof options == 'string' ? options : encoding,
flag,
mode,
};
}
return {
encoding: typeof options?.encoding == 'string' ? options.encoding : encoding,
flag: typeof options?.flag == 'string' ? options.flag : flag,
mode: normalizeMode('mode' in options ? options?.mode : null, mode),
};
}

@@ -106,0 +94,0 @@ /**

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

}): Uint8Array;
export declare function readFileSync(filename: string, options: {
encoding: string;
export declare function readFileSync(filename: string, options: (Node.BaseEncodingOptions & {
flag?: string;
}): string;
export declare function readFileSync(filename: string, encoding: string): string;
}) | BufferEncoding): string;
/**

@@ -110,4 +108,3 @@ * Synchronously writes data to a file, replacing the file if it already

*/
export declare function appendFileSync(filename: string, data: FileContents, options?: Node.WriteFileOptions): void;
export declare function appendFileSync(filename: string, data: FileContents, encoding?: string): void;
export declare function appendFileSync(filename: string, data: FileContents, arg3?: Node.WriteFileOptions): void;
/**

@@ -114,0 +111,0 @@ * Synchronous `fstat`.

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

}
const data = readFileSync(oldPath);
writeFileSync(newPath, data);
writeFileSync(newPath, readFileSync(oldPath));
unlinkSync(oldPath);

@@ -109,7 +108,7 @@ }

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

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

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

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

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

@@ -235,2 +234,13 @@ // Delete file.

}
/**
* Asynchronously append data to a file, creating the file if it not yet
* exists.
*
* @param filename
* @param data
* @param options
* @option options encoding Defaults to `'utf8'`.
* @option options mode Defaults to `0644`.
* @option options flag Defaults to `'a'`.
*/
export function appendFileSync(filename, data, arg3) {

@@ -422,3 +432,3 @@ const options = normalizeOptions(arg3, 'utf8', 'a', 0o644);

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

@@ -425,0 +435,0 @@ writeFileSync(path, target);

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

export declare function flagToNumber(flag: string): number;
/**
* Parses a flag as a mode (W_OK, R_OK, and/or X_OK)
* @param flag the flag to parse
*/
export declare function flagToMode(flag: string): number;

@@ -34,0 +38,0 @@ export declare function isReadable(flag: string): boolean;

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

}
/**
* Parses a flag as a mode (W_OK, R_OK, and/or X_OK)
* @param flag the flag to parse
*/
export function flagToMode(flag) {

@@ -327,11 +331,12 @@ let mode = 0;

}
this._buffer.set(buffer.slice(offset, offset + length), position);
const len = this._buffer.byteOffset;
const slice = buffer.slice(offset, offset + length);
this._buffer.set(slice, position);
const bytesWritten = slice.byteLength;
this.stats.mtimeMs = Date.now();
if (isSynchronous(this.flag)) {
this.syncSync();
return len;
return bytesWritten;
}
this.position = position + len;
return len;
this.position = position + bytesWritten;
return bytesWritten;
}

@@ -394,5 +399,2 @@ /**

chmodSync(mode) {
if (!this.fs.metadata().supportsProperties) {
throw new ApiError(ErrorCode.ENOTSUP);
}
this._dirty = true;

@@ -416,5 +418,2 @@ this.stats.chmod(mode);

chownSync(uid, gid) {
if (!this.fs.metadata().supportsProperties) {
throw new ApiError(ErrorCode.ENOTSUP);
}
this._dirty = true;

@@ -428,5 +427,2 @@ this.stats.chown(uid, gid);

utimesSync(atime, mtime) {
if (!this.fs.metadata().supportsProperties) {
throw new ApiError(ErrorCode.ENOTSUP);
}
this._dirty = true;

@@ -433,0 +429,0 @@ this.stats.atime = atime;

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

if (!inode) {
throw ApiError.ENOENT(path);
throw ApiError.With('ENOENT', path, 'stat');
}

@@ -323,3 +323,3 @@ if (inode.isDirectory()) {

if (!inode) {
throw ApiError.ENOENT(path);
throw ApiError.With('ENOENT', path, 'statSync');
}

@@ -342,6 +342,6 @@ if (inode.isDirectory()) {

if (!inode) {
throw ApiError.ENOENT(path);
throw ApiError.With('ENOENT', path, 'openFile');
}
if (!inode.toStats().hasAccess(flagToMode(flag), cred)) {
throw ApiError.EACCES(path);
throw ApiError.With('EACCESS', path, 'openFile');
}

@@ -362,6 +362,6 @@ if (inode.isDirectory()) {

if (!inode) {
throw ApiError.ENOENT(path);
throw ApiError.With('ENOENT', path, 'openFileSync');
}
if (!inode.toStats().hasAccess(flagToMode(flag), cred)) {
throw ApiError.EACCES(path);
throw ApiError.With('EACCES', path, 'openFileSync');
}

@@ -378,3 +378,3 @@ if (inode.isDirectory()) {

if (!inode) {
throw ApiError.ENOENT(path);
throw ApiError.With('ENOENT', path, 'readdir');
}

@@ -384,3 +384,3 @@ if (inode.isDirectory()) {

}
throw ApiError.ENOTDIR(path);
throw ApiError.With('ENOTDIR', path, 'readdir');
}

@@ -391,3 +391,3 @@ readdirSync(path) {

if (!inode) {
throw ApiError.ENOENT(path);
throw ApiError.With('ENOENT', path, 'readdirSync');
}

@@ -397,3 +397,3 @@ if (inode.isDirectory()) {

}
throw ApiError.ENOTDIR(path);
throw ApiError.With('ENOTDIR', path, 'readdirSync');
}

@@ -400,0 +400,0 @@ }

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

* Checks if a given user/group has access to this item
* @param mode The request access as 4 bits (unused, read, write, execute)
* @param uid The requesting UID
* @param gid The requesting GID
* @param mode The requested access, combination of W_OK, R_OK, and X_OK
* @param cred The requesting credentials
* @returns True if the request has access, false if the request does not

@@ -154,0 +153,0 @@ * @internal

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

import { S_IFDIR, S_IFLNK, S_IFMT, S_IFREG } from './emulation/constants.js';
import { S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, S_IRWXG, S_IRWXO, S_IRWXU } from './emulation/constants.js';
/**

@@ -148,5 +148,4 @@ * Indicates the type of the given file. Applied to 'mode'.

* Checks if a given user/group has access to this item
* @param mode The request access as 4 bits (unused, read, write, execute)
* @param uid The requesting UID
* @param gid The requesting GID
* @param mode The requested access, combination of W_OK, R_OK, and X_OK
* @param cred The requesting credentials
* @returns True if the request has access, false if the request does not

@@ -160,20 +159,5 @@ * @internal

}
const perms = this.mode & ~S_IFMT;
let uMode = 0xf, gMode = 0xf, wMode = 0xf;
if (cred.euid == this.uid) {
const uPerms = (0xf00 & perms) >> 8;
uMode = (mode ^ uPerms) & mode;
}
if (cred.egid == this.gid) {
const gPerms = (0xf0 & perms) >> 4;
gMode = (mode ^ gPerms) & mode;
}
const wPerms = 0xf & perms;
wMode = (mode ^ wPerms) & mode;
/*
Result = 0b0xxx (read, write, execute)
If any bits are set that means the request does not have that permission.
*/
const result = uMode & gMode & wMode;
return !result;
// Mask for
const adjusted = (cred.uid == this.uid ? S_IRWXU : 0) | (cred.gid == this.gid ? S_IRWXG : 0) | S_IRWXO;
return (mode & this.mode & adjusted) == mode;
}

@@ -180,0 +164,0 @@ /**

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

case 'ascii':
return new Uint8Array(Array.from(input).map(char => char.charCodeAt(0) & 0x7f));
case 'latin1':

@@ -128,3 +129,3 @@ case 'binary':

case 'base64':
return encode(atob(input), 'utf-8');
return encode(atob(input), 'binary');
case 'base64url':

@@ -156,2 +157,5 @@ return encode(input.replace('_', '/').replace('-', '+'), 'base64');

case 'ascii':
return Array.from(input)
.map(char => String.fromCharCode(char & 0x7f))
.join('');
case 'latin1':

@@ -192,3 +196,3 @@ case 'binary':

case 'base64':
return btoa(decode(input, 'utf-8'));
return btoa(decode(input, 'binary'));
case 'base64url':

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

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

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

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

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc