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

@zenfs/core

Package Overview
Dependencies
Maintainers
0
Versions
171
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 1.9.4 to 1.9.5

1

dist/backends/memory.d.ts

@@ -13,3 +13,2 @@ import { StoreFS } from './store/fs.js';

sync(): Promise<void>;
clearSync(): void;
transaction(): SyncMapTransaction;

@@ -16,0 +15,0 @@ }

@@ -15,5 +15,2 @@ import { StoreFS } from './store/fs.js';

async sync() { }
clearSync() {
this.clear();
}
transaction() {

@@ -20,0 +17,0 @@ return new SyncMapTransaction(this);

2

dist/backends/port/fs.js

@@ -148,5 +148,5 @@ import { pick } from 'utilium';

attachFS(port, fs);
stopAndReplay(fs);
await stopAndReplay(fs);
info('Resolved remote mount: ' + fs.toString());
return fs;
}

@@ -13,3 +13,3 @@ import type { TransferListItem } from 'node:worker_threads';

postMessage(value: unknown, transfer?: TransferListItem[]): void;
on?(event: 'message', listener: (value: unknown) => void): this;
on?(event: 'message' | 'online', listener: (value: unknown) => void): this;
off?(event: 'message', listener: (value: unknown) => void): this;

@@ -74,2 +74,6 @@ addEventListener?(type: 'message', listener: (ev: _MessageEvent) => void): void;

export declare function detach<T extends Message>(port: Port, handler: (message: T) => unknown): void;
export declare function catchMessages<T extends Backend>(port: Port): (fs: FilesystemOf<T>) => void;
export declare function catchMessages<T extends Backend>(port: Port): (fs: FilesystemOf<T>) => Promise<void>;
/**
* @internal
*/
export declare function waitOnline(port: Port): Promise<void>;

@@ -67,3 +67,3 @@ import { Errno, ErrnoError } from '../../internal/error.js';

port['on' in port ? 'on' : 'addEventListener']('message', (message) => {
handler('data' in message ? message.data : message);
handler(typeof message == 'object' && message !== null && 'data' in message ? message.data : message);
});

@@ -76,3 +76,3 @@ }

port['off' in port ? 'off' : 'removeEventListener']('message', (message) => {
handler('data' in message ? message.data : message);
handler(typeof message == 'object' && message !== null && 'data' in message ? message.data : message);
});

@@ -84,9 +84,20 @@ }

attach(port, handler);
return function (fs) {
return async function (fs) {
detach(port, handler);
for (const event of events) {
const request = 'data' in event ? event.data : event;
void handleRequest(port, fs, request);
await handleRequest(port, fs, request);
}
};
}
/**
* @internal
*/
export async function waitOnline(port) {
if (!('on' in port))
return; // Only need to wait in Node.js
const online = Promise.withResolvers();
setTimeout(online.reject, 500);
port.on('online', online.resolve);
await online.promise;
}
import type * as fs from 'node:fs';
import type { ClassLike, OptionalTuple } from 'utilium';
import { ErrnoError } from './internal/error.js';
import type { AbsolutePath } from './vfs/path.js';
declare global {

@@ -57,3 +56,3 @@ function atob(data: string): string;

*/
export declare function normalizePath(p: fs.PathLike): AbsolutePath;
export declare function normalizePath(p: fs.PathLike, noResolve?: boolean): string;
/**

@@ -60,0 +59,0 @@ * Normalizes options

@@ -104,4 +104,11 @@ import { Errno, ErrnoError } from './internal/error.js';

*/
export function normalizePath(p) {
export function normalizePath(p, noResolve = false) {
if (p instanceof URL) {
if (p.protocol != 'file:')
throw new ErrnoError(Errno.EINVAL, 'URLs must use the file: protocol');
p = p.pathname;
}
p = p.toString();
if (p.startsWith('file://'))
p = p.slice('file://'.length);
if (p.includes('\x00')) {

@@ -113,3 +120,4 @@ throw new ErrnoError(Errno.EINVAL, 'Path can not contain null character');

}
return resolve(p.replaceAll(/[/\\]+/g, '/'));
p = p.replaceAll(/[/\\]+/g, '/');
return noResolve ? p : resolve(p);
}

@@ -116,0 +124,0 @@ /**

@@ -92,5 +92,4 @@ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {

const numMode = normalizeMode(mode, -1);
if (numMode < 0) {
if (numMode < 0)
throw new ErrnoError(Errno.EINVAL, 'Invalid mode.');
}
await this.file.chmod(numMode);

@@ -491,6 +490,6 @@ this._emitChange();

const mode = normalizeMode(opt.mode, 0o644), flag = parseFlag(opt.flag);
const { fullPath: realpath, fs, path: resolved, stats } = await _resolve($, path.toString(), opt.preserveSymlinks);
const { fullPath, fs, path: resolved, stats } = await _resolve($, path.toString(), opt.preserveSymlinks);
if (!stats) {
if ((!isWriteable(flag) && !isAppendable(flag)) || flag == 'r+') {
throw ErrnoError.With('ENOENT', realpath, '_open');
throw ErrnoError.With('ENOENT', fullPath, '_open');
}

@@ -500,6 +499,6 @@ // Create the file

if (config.checkAccess && !parentStats.hasAccess(constants.W_OK, $)) {
throw ErrnoError.With('EACCES', dirname(realpath), '_open');
throw ErrnoError.With('EACCES', dirname(fullPath), '_open');
}
if (!parentStats.isDirectory()) {
throw ErrnoError.With('ENOTDIR', dirname(realpath), '_open');
throw ErrnoError.With('ENOTDIR', dirname(fullPath), '_open');
}

@@ -512,6 +511,6 @@ const { euid: uid, egid: gid } = (_a = $ === null || $ === void 0 ? void 0 : $.credentials) !== null && _a !== void 0 ? _a : credentials;

if (config.checkAccess && !stats.hasAccess(flagToMode(flag), $)) {
throw ErrnoError.With('EACCES', realpath, '_open');
throw ErrnoError.With('EACCES', fullPath, '_open');
}
if (isExclusive(flag)) {
throw ErrnoError.With('EEXIST', realpath, '_open');
throw ErrnoError.With('EEXIST', fullPath, '_open');
}

@@ -775,7 +774,7 @@ const handle = new FileHandle(await fs.openFile(resolved, flag), $);

}
if (await exists.call(this, path)) {
throw ErrnoError.With('EEXIST', path.toString(), 'symlink');
}
path = normalizePath(path);
if (await exists.call(this, path))
throw ErrnoError.With('EEXIST', path, 'symlink');
const handle = __addDisposableResource(env_5, await _open(this, path, { flag: 'w+', mode: 0o644, preserveSymlinks: true }), true);
await handle.writeFile(target.toString());
await handle.writeFile(normalizePath(target, true));
await handle.file.chmod(constants.S_IFLNK);

@@ -973,4 +972,3 @@ }

const target = resolve(realDir, (await readlink.call($, maybePath)).toString());
const real = await realpath.call($, target);
return { ...resolved, fullPath: real, stats };
return await _resolve($, target);
}

@@ -977,0 +975,0 @@ catch (e) {

@@ -238,7 +238,8 @@ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {

}
function _readFileSync(fname, flag, preserveSymlinks) {
function _readFileSync(path, flag, preserveSymlinks) {
const env_2 = { stack: [], error: void 0, hasError: false };
try {
path = normalizePath(path);
// Get file.
const file = __addDisposableResource(env_2, _openSync.call(this, fname, { flag, mode: 0o644, preserveSymlinks }), false);
const file = __addDisposableResource(env_2, _openSync.call(this, path, { flag, mode: 0o644, preserveSymlinks }), false);
const stat = file.statSync();

@@ -264,3 +265,3 @@ // Allocate buffer.

}
const data = Buffer.from(_readFileSync.call(this, typeof path == 'number' ? fd2file(path).path : path.toString(), options.flag, false));
const data = Buffer.from(_readFileSync.call(this, typeof path == 'number' ? fd2file(path).path : path, options.flag, false));
return options.encoding ? data.toString(options.encoding) : data;

@@ -569,3 +570,3 @@ }

}
writeFileSync.call(this, path, target.toString());
writeFileSync.call(this, path, normalizePath(target, true));
const file = _openSync.call(this, path, { flag: 'r+', mode: 0o644, preserveSymlinks: true });

@@ -576,3 +577,3 @@ file.chmodSync(constants.S_IFLNK);

export function readlinkSync(path, options) {
const value = Buffer.from(_readFileSync.call(this, path.toString(), 'r', true));
const value = Buffer.from(_readFileSync.call(this, path, 'r', true));
const encoding = typeof options == 'object' ? options === null || options === void 0 ? void 0 : options.encoding : options;

@@ -664,4 +665,3 @@ if (encoding == 'buffer') {

const target = resolve(realDir, readlinkSync.call($, maybePath).toString());
const real = realpathSync.call($, target);
return { ...resolved, fullPath: real, stats };
return _resolveSync($, target);
}

@@ -668,0 +668,0 @@ catch (e) {

{
"name": "@zenfs/core",
"version": "1.9.4",
"version": "1.9.5",
"description": "A filesystem, anywhere",

@@ -5,0 +5,0 @@ "funding": {

@@ -54,3 +54,3 @@ #!/usr/bin/env node

-q, --quiet Don't output normal messages
-l, --logs <level> Change the default log level for test output. Level can be a number or string
-l, --logs <level> Change the default log level for test output. Level can be a number or string
-N, --file-names Use full file paths for tests from setup files instead of the base name

@@ -170,5 +170,8 @@ -C, --ci Continuous integration (CI) mode. This interacts with the Github

try {
execSync(`tsx ${options.inspect ? 'inspect' : ''} --test --experimental-test-coverage 'tests/*.test.ts' 'tests/**/!(fs)/*.test.ts'`, {
stdio: ['ignore', options.verbose ? 'inherit' : 'ignore', 'inherit'],
});
execSync(
`tsx ${options.inspect ? 'inspect' : ''} ${options.force ? '--test-force-exit' : ''} --test --experimental-test-coverage 'tests/*.test.ts' 'tests/**/!(fs)/*.test.ts'`,
{
stdio: ['ignore', options.verbose ? 'inherit' : 'ignore', 'inherit'],
}
);
await pass();

@@ -175,0 +178,0 @@ } catch {

@@ -5,2 +5,3 @@ import assert from 'node:assert/strict';

import { Port, attachFS } from '../../dist/backends/port/fs.js';
import { waitOnline } from '../../dist/backends/port/rpc.js';
import type { InMemoryStore, StoreFS } from '../../dist/index.js';

@@ -53,2 +54,3 @@ import { ErrnoError, InMemory, configure, configureSingle, fs, resolveMountConfig } from '../../dist/index.js';

const configPort = new Worker(import.meta.dirname + '/config.worker.js');
await waitOnline(configPort);

@@ -59,3 +61,3 @@ await suite('Remote FS with resolveRemoteMount', () => {

test('Configuration', async () => {
await configureSingle({ backend: Port, port: configPort, timeout: 500 });
await configureSingle({ backend: Port, port: configPort, timeout: 100 });
});

@@ -68,7 +70,7 @@

test('Read', async () => {
assert((await fs.promises.readFile('/test', 'utf8')) === content);
assert.equal(await fs.promises.readFile('/test', 'utf8'), content);
});
});
await configPort?.terminate();
await configPort.terminate();
configPort.unref();

@@ -86,3 +88,3 @@

attachFS(channel.port2, tmpfs);
await configureSingle({ backend: Port, port: channel.port1, disableAsyncCache: true, timeout: 250 });
await configureSingle({ backend: Port, port: channel.port1, disableAsyncCache: true, timeout: 100 });
});

@@ -96,3 +98,3 @@

fs.mount('/tmp', tmpfs);
assert(fs.readFileSync('/tmp/test', 'utf8') == content);
assert.equal(fs.readFileSync('/tmp/test', 'utf8'), content);
fs.umount('/tmp');

@@ -102,3 +104,3 @@ });

test('read', async () => {
assert((await fs.promises.readFile('/test', 'utf8')) === content);
assert.equal(await fs.promises.readFile('/test', 'utf8'), content);
});

@@ -111,2 +113,4 @@

channel.port1.close();
channel.port2.close();
channel.port1.unref();

@@ -123,3 +127,3 @@ channel.port2.unref();

test('Configuration', async () => {
await configureSingle({ backend: Port, port: remotePort, timeout: 500 });
await configureSingle({ backend: Port, port: remotePort, timeout: 100 });
});

@@ -134,4 +138,2 @@

});
test('Cleanup', async () => {});
});

@@ -138,0 +140,0 @@

import assert from 'node:assert/strict';
import { suite, test } from 'node:test';
import { basename, dirname, extname, join, normalize, resolve } from '../../dist/vfs/path.js';
import * as fs from '../../dist/vfs/index.js';

@@ -34,2 +35,13 @@ suite('Path emulation', () => {

});
test('file:// URL (string)', () => {
fs.writeFileSync('/example.txt', 'Yay');
assert.equal(fs.readFileSync('file:///example.txt', 'utf-8'), 'Yay');
});
test('file:// URL (URL)', () => {
fs.writeFileSync('/example.txt', 'Yay');
const url = new URL('file:///example.txt');
assert.equal(fs.readFileSync(url, 'utf-8'), 'Yay');
});
});

@@ -30,2 +30,27 @@ import assert from 'node:assert/strict';

test('nested symlinks', async () => {
// Create the real directory structure
const realDir = '/real-dir';
const realFile = '/real-dir/realfile.txt';
const fileContent = 'hello world';
await fs.promises.mkdir(realDir);
await fs.promises.writeFile(realFile, fileContent);
// Create first symlink (symlink-dir -> real-dir)
const symlinkDir = '/symlink-dir';
await fs.promises.symlink(realDir, symlinkDir);
const symfile = 'symfile.txt';
const symlinkFile = join(realDir, symfile);
// Create second symlink (symlink-dir -> real-dir)
await fs.promises.symlink(realFile, symlinkFile);
// Now access file through nested symlinks
const nestedPath = join(symlinkDir, symfile);
// Verify realpath resolution
const resolvedPath = await fs.promises.realpath(nestedPath);
assert.equal(resolvedPath, realFile);
// Verify content can be read through nested symlinks
const content = await fs.promises.readFile(nestedPath, 'utf8');
assert.notEqual(content, '/real-dir/realfile.txt');
assert.equal(content, fileContent);
});
test('unlink', async () => {

@@ -32,0 +57,0 @@ await fs.promises.unlink(symlink);

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