the-forest/client/node_modules/enhanced-resolve/lib/util/path.js

204 lines
4.9 KiB
JavaScript
Raw Normal View History

2024-09-17 20:35:18 -04:00
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const path = require("path");
const CHAR_HASH = "#".charCodeAt(0);
const CHAR_SLASH = "/".charCodeAt(0);
const CHAR_BACKSLASH = "\\".charCodeAt(0);
const CHAR_A = "A".charCodeAt(0);
const CHAR_Z = "Z".charCodeAt(0);
const CHAR_LOWER_A = "a".charCodeAt(0);
const CHAR_LOWER_Z = "z".charCodeAt(0);
const CHAR_DOT = ".".charCodeAt(0);
const CHAR_COLON = ":".charCodeAt(0);
const posixNormalize = path.posix.normalize;
const winNormalize = path.win32.normalize;
/**
* @enum {number}
*/
const PathType = Object.freeze({
Empty: 0,
Normal: 1,
Relative: 2,
AbsoluteWin: 3,
AbsolutePosix: 4,
Internal: 5
});
exports.PathType = PathType;
const invalidSegmentRegEx =
/(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))?(\\|\/|$)/i;
exports.invalidSegmentRegEx = invalidSegmentRegEx;
const deprecatedInvalidSegmentRegEx =
/(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))(\\|\/|$)/i;
exports.deprecatedInvalidSegmentRegEx = deprecatedInvalidSegmentRegEx;
/**
* @param {string} p a path
* @returns {PathType} type of path
*/
const getType = p => {
switch (p.length) {
case 0:
return PathType.Empty;
case 1: {
const c0 = p.charCodeAt(0);
switch (c0) {
case CHAR_DOT:
return PathType.Relative;
case CHAR_SLASH:
return PathType.AbsolutePosix;
case CHAR_HASH:
return PathType.Internal;
}
return PathType.Normal;
}
case 2: {
const c0 = p.charCodeAt(0);
switch (c0) {
case CHAR_DOT: {
const c1 = p.charCodeAt(1);
switch (c1) {
case CHAR_DOT:
case CHAR_SLASH:
return PathType.Relative;
}
return PathType.Normal;
}
case CHAR_SLASH:
return PathType.AbsolutePosix;
case CHAR_HASH:
return PathType.Internal;
}
const c1 = p.charCodeAt(1);
if (c1 === CHAR_COLON) {
if (
(c0 >= CHAR_A && c0 <= CHAR_Z) ||
(c0 >= CHAR_LOWER_A && c0 <= CHAR_LOWER_Z)
) {
return PathType.AbsoluteWin;
}
}
return PathType.Normal;
}
}
const c0 = p.charCodeAt(0);
switch (c0) {
case CHAR_DOT: {
const c1 = p.charCodeAt(1);
switch (c1) {
case CHAR_SLASH:
return PathType.Relative;
case CHAR_DOT: {
const c2 = p.charCodeAt(2);
if (c2 === CHAR_SLASH) return PathType.Relative;
return PathType.Normal;
}
}
return PathType.Normal;
}
case CHAR_SLASH:
return PathType.AbsolutePosix;
case CHAR_HASH:
return PathType.Internal;
}
const c1 = p.charCodeAt(1);
if (c1 === CHAR_COLON) {
const c2 = p.charCodeAt(2);
if (
(c2 === CHAR_BACKSLASH || c2 === CHAR_SLASH) &&
((c0 >= CHAR_A && c0 <= CHAR_Z) ||
(c0 >= CHAR_LOWER_A && c0 <= CHAR_LOWER_Z))
) {
return PathType.AbsoluteWin;
}
}
return PathType.Normal;
};
exports.getType = getType;
/**
* @param {string} p a path
* @returns {string} the normalized path
*/
const normalize = p => {
switch (getType(p)) {
case PathType.Empty:
return p;
case PathType.AbsoluteWin:
return winNormalize(p);
case PathType.Relative: {
const r = posixNormalize(p);
return getType(r) === PathType.Relative ? r : `./${r}`;
}
}
return posixNormalize(p);
};
exports.normalize = normalize;
/**
* @param {string} rootPath the root path
* @param {string | undefined} request the request path
* @returns {string} the joined path
*/
const join = (rootPath, request) => {
if (!request) return normalize(rootPath);
const requestType = getType(request);
switch (requestType) {
case PathType.AbsolutePosix:
return posixNormalize(request);
case PathType.AbsoluteWin:
return winNormalize(request);
}
switch (getType(rootPath)) {
case PathType.Normal:
case PathType.Relative:
case PathType.AbsolutePosix:
return posixNormalize(`${rootPath}/${request}`);
case PathType.AbsoluteWin:
return winNormalize(`${rootPath}\\${request}`);
}
switch (requestType) {
case PathType.Empty:
return rootPath;
case PathType.Relative: {
const r = posixNormalize(rootPath);
return getType(r) === PathType.Relative ? r : `./${r}`;
}
}
return posixNormalize(rootPath);
};
exports.join = join;
/** @type {Map<string, Map<string, string | undefined>>} */
const joinCache = new Map();
/**
* @param {string} rootPath the root path
* @param {string} request the request path
* @returns {string} the joined path
*/
const cachedJoin = (rootPath, request) => {
/** @type {string | undefined} */
let cacheEntry;
let cache = joinCache.get(rootPath);
if (cache === undefined) {
joinCache.set(rootPath, (cache = new Map()));
} else {
cacheEntry = cache.get(request);
if (cacheEntry !== undefined) return cacheEntry;
}
cacheEntry = join(rootPath, request);
cache.set(request, cacheEntry);
return cacheEntry;
};
exports.cachedJoin = cachedJoin;