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

@lix-js/fs

Package Overview
Dependencies
Maintainers
0
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lix-js/fs - npm Package Compare versions

Comparing version 2.1.0 to 2.2.0

dist/implementations.test.d.ts

3

dist/index.d.ts
export type { NodeishFilesystem, NodeishStats } from "./NodeishFilesystemApi.js";
export { createNodeishMemoryFs, toSnapshot, fromSnapshot, type Snapshot } from "./memoryFs.js";
export { normalizePath, normalPath, // FIXME: unify with normalizePath
getBasename, getDirname, assertIsAbsolutePath, } from "./utilities/helpers.js";
export { normalizePath, getBasename, getDirname, assertIsAbsolutePath, } from "./utilities/helpers.js";
//# sourceMappingURL=index.d.ts.map
export { createNodeishMemoryFs, toSnapshot, fromSnapshot } from "./memoryFs.js";
export { normalizePath, normalPath, // FIXME: unify with normalizePath
getBasename, getDirname, assertIsAbsolutePath, } from "./utilities/helpers.js";
export { normalizePath, getBasename, getDirname, assertIsAbsolutePath, } from "./utilities/helpers.js";
import { FilesystemError } from "./errors/FilesystemError.js";
import { normalPath, getBasename, getDirname } from "./utilities/helpers.js";
import { normalizePath, getBasename, getDirname } from "./utilities/helpers.js";
export function toSnapshot(fs) {

@@ -100,8 +100,10 @@ return {

async function stat(path) {
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const stats = state.fsStats.get(path);
if (stats === undefined)
if (stats === undefined) {
throw new FilesystemError("ENOENT", path, "stat");
if (stats.symlinkTarget)
}
if (stats.symlinkTarget) {
return stat(stats.symlinkTarget);
}
return Object.assign({}, stats);

@@ -111,8 +113,10 @@ }

async function lstat(path) {
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const stats = state.fsStats.get(path);
if (stats === undefined)
if (stats === undefined) {
throw new FilesystemError("ENOENT", path, "lstat");
if (!stats.symlinkTarget)
}
if (!stats.symlinkTarget) {
return stat(path);
}
return Object.assign({}, stats);

@@ -123,3 +127,3 @@ }

_createPlaceholder: async function (path, options) {
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const dirName = getDirname(path);

@@ -148,3 +152,3 @@ const baseName = getBasename(path);

_isPlaceholder: function (path) {
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const entry = state.fsMap.get(path);

@@ -157,3 +161,3 @@ if (entry && "placeholder" in entry) {

writeFile: async function (path, data, options) {
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const dirName = getDirname(path);

@@ -164,4 +168,5 @@ const baseName = getBasename(path);

throw new FilesystemError("ENOENT", path, "writeFile");
let inodeData;
if (typeof data === "string") {
data = Buffer.from(new TextEncoder().encode(data));
inodeData = Buffer.from(new TextEncoder().encode(data));
}

@@ -172,4 +177,7 @@ else if (!(data instanceof Uint8Array)) {

else if (!Buffer.isBuffer(data)) {
data = Buffer.from(data);
inodeData = Buffer.from(data);
}
else {
inodeData = data;
}
parentDir.add(baseName);

@@ -182,3 +190,3 @@ newStatEntry({

});
state.fsMap.set(path, data);
state.fsMap.set(path, inodeData);
for (const listener of listeners) {

@@ -193,3 +201,3 @@ listener({ eventType: "rename", filename: dirName + baseName });

const decoder = new TextDecoder();
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const file = state.fsMap.get(path);

@@ -207,3 +215,3 @@ if (file instanceof Set)

readdir: async function (path) {
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const dir = state.fsMap.get(path);

@@ -217,3 +225,3 @@ if (dir instanceof Set)

mkdir: async function mkdir(path, options) {
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const dirName = getDirname(path);

@@ -250,3 +258,3 @@ const baseName = getBasename(path);

const parentRes = await mkdir(parent, options);
await mkdir(path, options);
await mkdir(path, { recursive: false }).catch(() => { });
return parentRes;

@@ -257,3 +265,3 @@ }

rm: async function rm(path, options) {
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const dirName = getDirname(path);

@@ -300,3 +308,3 @@ const baseName = getBasename(path);

watch: function (path, options) {
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const watchName = getBasename(path);

@@ -372,3 +380,3 @@ const watchDir = getDirname(path);

rmdir: async function (path) {
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const dirName = getDirname(path);

@@ -395,5 +403,9 @@ const baseName = getBasename(path);

symlink: async function (target, path) {
path = normalPath(path);
target = target.startsWith("/") ? target : `${path}/../${target}`;
const targetInode = state.fsMap.get(normalPath(target));
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const rawTarget = target.startsWith("/") ? target : `${path}/../${target}`;
const targetWithTrailing = normalizePath(rawTarget, {
trailingSlash: "always",
leadingSlash: "always",
});
const targetInode = state.fsMap.get(targetWithTrailing);
const parentDir = state.fsMap.get(getDirname(path));

@@ -418,7 +430,7 @@ if (state.fsMap.get(path)) {

modeBits: 0o777,
target,
target: rawTarget,
});
},
unlink: async function (path) {
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const targetStats = state.fsStats.get(path);

@@ -440,3 +452,3 @@ const target = state.fsMap.get(path);

readlink: async function (path) {
path = normalPath(path);
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const linkStats = await lstat(path);

@@ -464,3 +476,4 @@ if (linkStats === undefined) {

const _kind = kind;
const oldStats = stats.get(normalPath(path));
const targetPath = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" });
const oldStats = stats.get(targetPath);
// We need to always bump by 1 second in case mtime did not change since last write to trigger iso git 1 second resolution change detection

@@ -470,3 +483,3 @@ const mtimeMs = Math.floor(currentTime / 1000) === (oldStats?.mtimeMs && Math.floor(oldStats?.mtimeMs / 1000))

: currentTime;
stats.set(normalPath(path), {
stats.set(targetPath, {
ctimeMs: oldStats?.ctimeMs || currentTime,

@@ -473,0 +486,0 @@ mtimeMs,

@@ -12,6 +12,8 @@ /**

export declare function assertIsAbsolutePath(path: string): void;
export declare function normalizePath(path: string, stripTrailing?: boolean): string;
export declare function normalPath(path: string): string;
export declare function normalizePath(path: string, { trailingSlash, leadingSlash }?: {
trailingSlash?: 'always' | 'strip';
leadingSlash?: 'always';
}): string;
export declare function getDirname(path: string): string;
export declare function getBasename(path: string): string;
//# sourceMappingURL=helpers.d.ts.map

@@ -20,25 +20,12 @@ /**

}
/*
* normalize-path <https://github.com/jonschlinkert/normalize-path>
*
* Copyright (c) 2014-2018, Jon Schlinkert.
* Released under the MIT License.
*/
export function normalizePath(path, stripTrailing) {
if (path === "\\" || path === "/")
export function normalizePath(path, { trailingSlash, leadingSlash } = {}) {
path = path.replace(/^\.\//, '/');
if (path === "\\" || path === "" || path === "/" || path === "." || path === "//.") {
return "/";
const len = path.length;
if (len <= 1)
}
if (path.length <= 1) {
return path;
// ensure that win32 namespaces has two leading slashes, so that the path is
// handled properly by the win32 version of path.parse() after being normalized
// https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces
let prefix = "";
if (len > 4 && path[3] === "\\") {
const ch = path[2];
if ((ch === "?" || ch === ".") && path.slice(0, 2) === "\\\\") {
path = path.slice(2);
prefix = "//";
}
}
const hadTrailingSlash = path[path.length - 1] === '/' || path[path.length - 1] === '\\';
const addleadingSlash = leadingSlash === 'always' || path[0] === '/' || path[0] === '\\';
const segs = path.split(/[/\\]+/);

@@ -50,53 +37,18 @@ const stack = [];

}
else if (seg !== ".") {
else if (seg && seg !== ".") {
stack.push(seg);
}
}
if (stripTrailing !== false && stack.at(-1) === "") {
stack.pop();
if ((trailingSlash !== 'strip') && (hadTrailingSlash || trailingSlash === 'always')) {
stack.push("");
}
return prefix + stack.join("/");
return addleadingSlash ? ('/' + stack.join("/")) : stack.join("/");
}
/**
* Removes extraneous dots and slashes, resolves relative paths and ensures the
* path begins and ends with '/'
* FIXME: unify with utilities/normalizePath!
*/
const dots = /(\/|^)(\.\/)+/g;
const slashes = /\/+/g;
const upreference = /(?<!\.\.)[^/]+\/\.\.\//;
export function normalPath(path) {
// const origPath = path
// FIXME: move to simple logic liek this:
// const newPath =
// path === "" || path === "/" || path === "." || path === "//."
// ? "/"
// : `/${path
// .split("/")
// .filter((elem) => elem !== "")
// .join("/")}/`
// return newPath
// all THIS is super slow and not needed:
// Append '/' to the beginning and end
path = `/${path}/`;
// Handle the edge case where a path begins with '/..'
path = path.replace(/^\/\.\./, "");
// Remove extraneous '.' and '/'
path = path.replace(dots, "/").replace(slashes, "/");
// Resolve relative paths if they exist
let match;
while ((match = path.match(upreference)?.[0])) {
path = path.replace(match, "");
}
// if (newPath !== path) {
// console.log({ in: origPath, out: path, newPath })
// }
return path;
}
export function getDirname(path) {
return normalPath(path
const dirname = path
.split("/")
.filter((x) => x)
.slice(0, -1)
.join("/") ?? path);
.join("/");
return normalizePath(dirname, { leadingSlash: 'always', trailingSlash: 'always' }) ?? path;
}

@@ -107,3 +59,3 @@ export function getBasename(path) {

.filter((x) => x)
.at(-1) ?? path);
.at(-1) ?? '');
}
{
"name": "@lix-js/fs",
"version": "2.1.0",
"version": "2.2.0",
"type": "module",

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

import { test, expect, afterAll, describe } from "vitest"
import type { NodeishFilesystem, FileChangeInfo } from "./NodeishFilesystemApi.ts"
// @ts-ignore
import { createNodeishMemoryFs, toSnapshot, fromSnapshot } from "./memoryFs.ts"

@@ -4,0 +5,0 @@

@@ -5,3 +5,2 @@ export type { NodeishFilesystem, NodeishStats } from "./NodeishFilesystemApi.js"

normalizePath,
normalPath, // FIXME: unify with normalizePath
getBasename,

@@ -8,0 +7,0 @@ getDirname,

import type { NodeishFilesystem, NodeishStats, FileChangeInfo } from "./NodeishFilesystemApi.js"
import { FilesystemError } from "./errors/FilesystemError.js"
import { normalPath, getBasename, getDirname } from "./utilities/helpers.js"
import { normalizePath, getBasename, getDirname } from "./utilities/helpers.js"

@@ -154,6 +154,11 @@ type Inode = Uint8Array | Set<string> | { placeholder: true }

async function stat(path: Parameters<NodeishFilesystem["stat"]>[0]): Promise<NodeishStats> {
path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const stats: NodeishStats | undefined = state.fsStats.get(path)
if (stats === undefined) throw new FilesystemError("ENOENT", path, "stat")
if (stats.symlinkTarget) return stat(stats.symlinkTarget)
if (stats === undefined) {
throw new FilesystemError("ENOENT", path, "stat")
}
if (stats.symlinkTarget) {
return stat(stats.symlinkTarget)
}
return Object.assign({}, stats)

@@ -164,6 +169,12 @@ }

async function lstat(path: Parameters<NodeishFilesystem["lstat"]>[0]) {
path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const stats: NodeishStats | undefined = state.fsStats.get(path)
if (stats === undefined) throw new FilesystemError("ENOENT", path, "lstat")
if (!stats.symlinkTarget) return stat(path)
if (stats === undefined) {
throw new FilesystemError("ENOENT", path, "lstat")
}
if (!stats.symlinkTarget) {
return stat(path)
}
return Object.assign({}, stats)

@@ -183,3 +194,3 @@ }

) {
path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const dirName = getDirname(path)

@@ -213,3 +224,3 @@ const baseName = getBasename(path)

_isPlaceholder: function (path: Parameters<NodeishFilesystem["writeFile"]>[0]) {
path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const entry = state.fsMap.get(path)

@@ -228,3 +239,3 @@

) {
path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const dirName = getDirname(path)

@@ -236,4 +247,5 @@ const baseName = getBasename(path)

let inodeData: Inode
if (typeof data === "string") {
data = Buffer.from(new TextEncoder().encode(data))
inodeData = Buffer.from(new TextEncoder().encode(data))
} else if (!(data instanceof Uint8Array)) {

@@ -246,3 +258,5 @@ throw new FilesystemError(

} else if (!Buffer.isBuffer(data)) {
data = Buffer.from(data)
inodeData = Buffer.from(data)
} else {
inodeData = data
}

@@ -259,3 +273,3 @@

state.fsMap.set(path, data)
state.fsMap.set(path, inodeData)
for (const listener of listeners) {

@@ -275,3 +289,3 @@ listener({ eventType: "rename", filename: dirName + baseName })

path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const file: Inode | undefined = state.fsMap.get(path)

@@ -288,3 +302,3 @@

readdir: async function (path: Parameters<NodeishFilesystem["readdir"]>[0]) {
path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const dir: Inode | undefined = state.fsMap.get(path)

@@ -300,5 +314,7 @@ if (dir instanceof Set) return [...dir.keys()]

): Promise<string | undefined> {
path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const dirName = getDirname(path)
const baseName = getBasename(path)
const parentDir: Inode | undefined = state.fsMap.get(dirName)

@@ -337,3 +353,3 @@

const parentRes = await mkdir(parent, options)
await mkdir(path, options)
await mkdir(path, { recursive: false }).catch(() => {})
return parentRes

@@ -349,3 +365,3 @@ }

) {
path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const dirName = getDirname(path)

@@ -407,3 +423,3 @@ const baseName = getBasename(path)

) {
path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const watchName = getBasename(path)

@@ -490,3 +506,3 @@ const watchDir = getDirname(path)

rmdir: async function (path: Parameters<NodeishFilesystem["rmdir"]>[0]) {
path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const dirName = getDirname(path)

@@ -522,5 +538,11 @@ const baseName = getBasename(path)

) {
path = normalPath(path)
target = target.startsWith("/") ? target : `${path}/../${target}`
const targetInode: Inode | undefined = state.fsMap.get(normalPath(target))
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const rawTarget = target.startsWith("/") ? target : `${path}/../${target}`
const targetWithTrailing = normalizePath(rawTarget, {
trailingSlash: "always",
leadingSlash: "always",
})
const targetInode: Inode | undefined = state.fsMap.get(targetWithTrailing)
const parentDir: Inode | undefined = state.fsMap.get(getDirname(path))

@@ -551,3 +573,3 @@

modeBits: 0o777,
target,
target: rawTarget,
})

@@ -557,3 +579,3 @@ },

unlink: async function (path: Parameters<NodeishFilesystem["unlink"]>[0]) {
path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const targetStats = state.fsStats.get(path)

@@ -579,3 +601,3 @@ const target: Inode | undefined = state.fsMap.get(path)

readlink: async function (path: Parameters<NodeishFilesystem["readlink"]>[0]) {
path = normalPath(path)
path = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const linkStats = await lstat(path)

@@ -623,4 +645,5 @@

const _kind = kind
const targetPath = normalizePath(path, { trailingSlash: "always", leadingSlash: "always" })
const oldStats = stats.get(normalPath(path))
const oldStats = stats.get(targetPath)

@@ -633,3 +656,3 @@ // We need to always bump by 1 second in case mtime did not change since last write to trigger iso git 1 second resolution change detection

stats.set(normalPath(path), {
stats.set(targetPath, {
ctimeMs: oldStats?.ctimeMs || currentTime,

@@ -636,0 +659,0 @@ mtimeMs,

@@ -21,32 +21,22 @@ /**

/*
* normalize-path <https://github.com/jonschlinkert/normalize-path>
*
* Copyright (c) 2014-2018, Jon Schlinkert.
* Released under the MIT License.
*/
export function normalizePath(path: string, stripTrailing?: boolean): string {
if (path === "\\" || path === "/") return "/"
export function normalizePath(path: string, { trailingSlash, leadingSlash }: { trailingSlash?: 'always' | 'strip', leadingSlash?: 'always' } = {}): string {
path = path.replace(/^\.\//, '/')
const len = path.length
if (len <= 1) return path
if (path === "\\" || path === "" || path === "/" || path === "." || path === "//.") {
return "/"
}
// ensure that win32 namespaces has two leading slashes, so that the path is
// handled properly by the win32 version of path.parse() after being normalized
// https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces
let prefix = ""
if (len > 4 && path[3] === "\\") {
const ch = path[2]
if ((ch === "?" || ch === ".") && path.slice(0, 2) === "\\\\") {
path = path.slice(2)
prefix = "//"
}
if (path.length <= 1) {
return path
}
const hadTrailingSlash = path[path.length - 1] === '/' || path[path.length - 1] === '\\'
const addleadingSlash = leadingSlash === 'always' || path[0] === '/' || path[0] === '\\'
const segs = path.split(/[/\\]+/)
const stack: string[] = []
for (const seg of segs) {
if (seg === "..") {
stack.pop()
} else if (seg !== ".") {
} else if (seg && seg !== ".") {
stack.push(seg)

@@ -56,58 +46,20 @@ }

if (stripTrailing !== false && stack.at(-1) === "") {
stack.pop()
if ((trailingSlash !== 'strip') && (hadTrailingSlash || trailingSlash === 'always')) {
stack.push("")
}
return prefix + stack.join("/")
return addleadingSlash ? ('/' + stack.join("/")) : stack.join("/")
}
/**
* Removes extraneous dots and slashes, resolves relative paths and ensures the
* path begins and ends with '/'
* FIXME: unify with utilities/normalizePath!
*/
const dots = /(\/|^)(\.\/)+/g
const slashes = /\/+/g
const upreference = /(?<!\.\.)[^/]+\/\.\.\//
export function normalPath(path: string): string {
// const origPath = path
// FIXME: move to simple logic liek this:
// const newPath =
// path === "" || path === "/" || path === "." || path === "//."
// ? "/"
// : `/${path
// .split("/")
// .filter((elem) => elem !== "")
// .join("/")}/`
// return newPath
export function getDirname(path: string): string {
const dirname = path
.split("/")
.filter((x) => x)
.slice(0, -1)
.join("/")
// all THIS is super slow and not needed:
// Append '/' to the beginning and end
path = `/${path}/`
// Handle the edge case where a path begins with '/..'
path = path.replace(/^\/\.\./, "")
// Remove extraneous '.' and '/'
path = path.replace(dots, "/").replace(slashes, "/")
// Resolve relative paths if they exist
let match
while ((match = path.match(upreference)?.[0])) {
path = path.replace(match, "")
}
// if (newPath !== path) {
// console.log({ in: origPath, out: path, newPath })
// }
return path
return normalizePath(dirname, { leadingSlash: 'always', trailingSlash: 'always'}) ?? path
}
export function getDirname(path: string): string {
return normalPath(
path
.split("/")
.filter((x) => x)
.slice(0, -1)
.join("/") ?? path
)
}
export function getBasename(path: string): string {
export function getBasename(path: string): string {
return (

@@ -117,4 +69,4 @@ path

.filter((x) => x)
.at(-1) ?? path
.at(-1) ?? ''
)
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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