Update Bot
This commit is contained in:
237
node_modules/@humanfs/core/src/path.js
generated
vendored
Normal file
237
node_modules/@humanfs/core/src/path.js
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
* @fileoverview The Path class.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
/* globals URL */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Types
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** @typedef{import("@humanfs/types").HfsImpl} HfsImpl */
|
||||
/** @typedef{import("@humanfs/types").HfsDirectoryEntry} HfsDirectoryEntry */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Normalizes a path to use forward slashes.
|
||||
* @param {string} filePath The path to normalize.
|
||||
* @returns {string} The normalized path.
|
||||
*/
|
||||
function normalizePath(filePath) {
|
||||
let startIndex = 0;
|
||||
let endIndex = filePath.length;
|
||||
|
||||
if (/[a-z]:\//i.test(filePath)) {
|
||||
startIndex = 3;
|
||||
}
|
||||
|
||||
if (filePath.startsWith("./")) {
|
||||
startIndex = 2;
|
||||
}
|
||||
|
||||
if (filePath.startsWith("/")) {
|
||||
startIndex = 1;
|
||||
}
|
||||
|
||||
if (filePath.endsWith("/")) {
|
||||
endIndex = filePath.length - 1;
|
||||
}
|
||||
|
||||
return filePath.slice(startIndex, endIndex).replace(/\\/g, "/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given name is a non-empty string, no equal to "." or "..",
|
||||
* and does not contain a forward slash or backslash.
|
||||
* @param {string} name The name to check.
|
||||
* @returns {void}
|
||||
* @throws {TypeError} When name is not valid.
|
||||
*/
|
||||
function assertValidName(name) {
|
||||
if (typeof name !== "string") {
|
||||
throw new TypeError("name must be a string");
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
throw new TypeError("name cannot be empty");
|
||||
}
|
||||
|
||||
if (name === ".") {
|
||||
throw new TypeError(`name cannot be "."`);
|
||||
}
|
||||
|
||||
if (name === "..") {
|
||||
throw new TypeError(`name cannot be ".."`);
|
||||
}
|
||||
|
||||
if (name.includes("/") || name.includes("\\")) {
|
||||
throw new TypeError(
|
||||
`name cannot contain a slash or backslash: "${name}"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Exports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
export class Path {
|
||||
/**
|
||||
* The steps in the path.
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
#steps;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {Iterable<string>} [steps] The steps to use for the path.
|
||||
* @throws {TypeError} When steps is not iterable.
|
||||
*/
|
||||
constructor(steps = []) {
|
||||
if (typeof steps[Symbol.iterator] !== "function") {
|
||||
throw new TypeError("steps must be iterable");
|
||||
}
|
||||
|
||||
this.#steps = [...steps];
|
||||
this.#steps.forEach(assertValidName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds steps to the end of the path.
|
||||
* @param {...string} steps The steps to add to the path.
|
||||
* @returns {void}
|
||||
*/
|
||||
push(...steps) {
|
||||
steps.forEach(assertValidName);
|
||||
this.#steps.push(...steps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last step from the path.
|
||||
* @returns {string} The last step in the path.
|
||||
*/
|
||||
pop() {
|
||||
return this.#steps.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator for steps in the path.
|
||||
* @returns {IterableIterator<string>} An iterator for the steps in the path.
|
||||
*/
|
||||
steps() {
|
||||
return this.#steps.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator for the steps in the path.
|
||||
* @returns {IterableIterator<string>} An iterator for the steps in the path.
|
||||
*/
|
||||
[Symbol.iterator]() {
|
||||
return this.steps();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the name (the last step) of the path.
|
||||
* @type {string}
|
||||
*/
|
||||
get name() {
|
||||
return this.#steps[this.#steps.length - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name (the last step) of the path.
|
||||
* @type {string}
|
||||
*/
|
||||
set name(value) {
|
||||
assertValidName(value);
|
||||
this.#steps[this.#steps.length - 1] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the size of the path.
|
||||
* @type {number}
|
||||
*/
|
||||
get size() {
|
||||
return this.#steps.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path as a string.
|
||||
* @returns {string} The path as a string.
|
||||
*/
|
||||
toString() {
|
||||
return this.#steps.join("/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new path based on the argument type. If the argument is a string,
|
||||
* it is assumed to be a file or directory path and is converted to a Path
|
||||
* instance. If the argument is a URL, it is assumed to be a file URL and is
|
||||
* converted to a Path instance. If the argument is a Path instance, it is
|
||||
* copied into a new Path instance. If the argument is an array, it is assumed
|
||||
* to be the steps of a path and is used to create a new Path instance.
|
||||
* @param {string|URL|Path|Array<string>} pathish The value to convert to a Path instance.
|
||||
* @returns {Path} A new Path instance.
|
||||
* @throws {TypeError} When pathish is not a string, URL, Path, or Array.
|
||||
* @throws {TypeError} When pathish is a string and is empty.
|
||||
*/
|
||||
static from(pathish) {
|
||||
if (typeof pathish === "string") {
|
||||
if (!pathish) {
|
||||
throw new TypeError("argument cannot be empty");
|
||||
}
|
||||
|
||||
return Path.fromString(pathish);
|
||||
}
|
||||
|
||||
if (pathish instanceof URL) {
|
||||
return Path.fromURL(pathish);
|
||||
}
|
||||
|
||||
if (pathish instanceof Path || Array.isArray(pathish)) {
|
||||
return new Path(pathish);
|
||||
}
|
||||
|
||||
throw new TypeError("argument must be a string, URL, Path, or Array");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Path instance from a string.
|
||||
* @param {string} fileOrDirPath The file or directory path to convert.
|
||||
* @returns {Path} A new Path instance.
|
||||
* @deprecated Use Path.from() instead.
|
||||
*/
|
||||
static fromString(fileOrDirPath) {
|
||||
return new Path(normalizePath(fileOrDirPath).split("/"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Path instance from a URL.
|
||||
* @param {URL} url The URL to convert.
|
||||
* @returns {Path} A new Path instance.
|
||||
* @throws {TypeError} When url is not a URL instance.
|
||||
* @throws {TypeError} When url.pathname is empty.
|
||||
* @throws {TypeError} When url.protocol is not "file:".
|
||||
* @deprecated Use Path.from() instead.
|
||||
*/
|
||||
static fromURL(url) {
|
||||
if (!(url instanceof URL)) {
|
||||
throw new TypeError("url must be a URL instance");
|
||||
}
|
||||
|
||||
if (!url.pathname || url.pathname === "/") {
|
||||
throw new TypeError("url.pathname cannot be empty");
|
||||
}
|
||||
|
||||
if (url.protocol !== "file:") {
|
||||
throw new TypeError(`url.protocol must be "file:"`);
|
||||
}
|
||||
|
||||
// Remove leading slash in pathname
|
||||
return new Path(normalizePath(url.pathname.slice(1)).split("/"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user