@lix-js/fs
Advanced tools
Comparing version 2.1.0 to 2.2.0
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
93848
34
2264